Как удалить первый столбец (который фактически является именами строк) из файла данных в 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 соответствуют частям, которые мы хотим удалить.