Как удалить первый столбец (который фактически является именами строк) из файла данных в Linux?

У меня есть файл данных со многими тысячами столбцов и строк. Я хочу удалить первый столбец, который на самом деле является счетчиком строк. Я использовал эту команду в linux:

cut -d " " -f 2- input.txt > output.txt

но ничего не изменилось в моем выпуске. Кто-нибудь знает, почему это не работает и что мне делать?

Вот как выглядит мой входной файл:

col1 col2 col3 col4 ...
     1 0 0 0 1
     2 0 1 0 1
     3 0 1 0 0
     4 0 0 0 0 
     5 0 1 1 1 
     6 1 1 1 0
     7 1 0 0 0 
     8 0 0 0 0
     9 1 0 0 0
     10 1 1 1 1
     11 0 0 0 1
    .
    .
    .

Я хочу, чтобы мой результат выглядел следующим образом:

col1 col2 col3 col4 ...
0 0 0 1
0 1 0 1
0 1 0 0
0 0 0 0 
0 1 1 1 
1 1 1 0
1 0 0 0 
0 0 0 0
1 0 0 0
1 1 1 1
0 0 0 1
.
.
.

Я также попробовал команду sed:

 sed '1d' input.file > output.file

Но он удаляет первую строку, а не первый столбец.

Может ли кто-нибудь меня навестить?

Ответ 1

@Karafka У меня были файлы CSV, поэтому я добавил разделитель "," (вы можете заменить своим

cut -d"," -f2- input.csv  > output.csv

Затем я использовал цикл, чтобы перебирать все файлы внутри каталога

# files are in the directory tmp/
for f in tmp/*
do
    name=`basename $f`
    echo "processing file : $name"
    #kepp all column excep the first one of each csv file 

    cut -d"," -f2- $f > new/$name
    #files using the same names are stored in directory new/  
done

Ответ 2

Идиоматическое использование разреза будет

cut -f2- input > output

если разделителем является вкладка ( "\ t" ).

Или просто с магией awk (будет работать как для пробела, так и для разделителя табуляции)

 awk '{$1=""}1' input | awk '{$1=$1}1' > output

первый awk удалит поле 1, но оставляет разделитель, второй awk удаляет разделитель. Разделитель вывода по умолчанию будет пространством, если вы хотите перейти на вкладку, добавьте -vOFS="\t" ко второму awk.

ОБНОВЛЕНО

Основываясь на вашем обновленном входе, проблема заключается в том, что начальные пробелы обрабатываются как несколько столбцов. Один из способов обращения - сначала удалить их перед подачей на срез

sed 's/^ *//' input | cut -d" " -f2- > output

или используйте альтернативу awk, которая будет работать и в этом случае.

Ответ 3

Вы можете использовать команду cut с опцией --complement:

cut -f1 -d" " --complement input.file > output.file

Это приведет к выводу всех столбцов, кроме первого.

Ответ 4

Как отмечает @karakfa, похоже, что это ведущий пробел, который вызывает ваши проблемы.

Вот sed oneliner для выполнения работы (который будет учитывать пробелы или табуляции):

sed -i.bak "s|^[ \t]\+[0-9]\+[ \t]\+||" input.txt

Объяснение:

-i       edit existing file in place
.bak     backup original file and add .bak file extension (can use whatever you like)

s        substitute
|        separator (easiest character to read as sed separator IMO)
^        start match at start of the line
[ \t]    match space or tab
\+       match one or more times (escape required so sed does not interpret '+' literally)
[0-9]    match any number 0 - 9

Как отмечено; файл input.txt будет отредактирован на месте. Исходное содержимое input.txt будет сохранено как input.txt.bak. Вместо этого используйте только -i, если вы не хотите делать резервную копию исходного файла.

Кроме того, если вы знаете, что они, безусловно, являются лидирующими пробелами (а не символами табуляции), вы можете сократить его до этого:

sed -i.bak "s|^ \+[0-9]\+[ \t]\+||" input.txt

Ответ 5

Вы также можете добиться этого с помощью grep:

grep -E -o '[[:digit:]]([[:space:]][[:digit:]]){3}$' input.txt

Который предполагает односимвольные цифры и пробелы. Чтобы разместить переменное количество пробелов и цифр, вы можете сделать:

grep -E -o '[[:digit:]]+([[:space:]]+[[:digit:]]+){3}$' input.txt

Если ваш grep поддерживает флаг -P (--perl-regexp), вы можете сделать:

grep -P -o '\d+(\s+\d+){3}$' input.txt

А вот несколько вариантов, если вы используете GNU sed:

sed 's/^\s\+\w\+\s\+//' input.txt
sed 's/^\s\+\S\+\s\+//' input.txt
sed 's/^\s\+[0-9]\+\s\+//' input.txt
sed 's/^\s\+[[:digit:]]\+\s\+//' input.txt

Обратите внимание, что регулярные выражения grep соответствуют частям, которые мы хотим сохранить, в то время как регулярные выражения sed соответствуют частям, которые мы хотим удалить.