Переупорядочить столбцы с помощью разреза
У меня есть файл в следующем формате
Column1 Column2
str1 1
str2 2
str3 3
Я хочу, чтобы столбцы были перегруппированы. Я попытался выполнить команду
cut -f2,1 file.txt
Команда не изменяет порядок столбцов. Любая идея, почему он не работает?
Спасибо.
Ответы
Ответ 1
Для справочной страницы cut(1)
:
Используйте один и только один из -b, -c или -f. Каждый СПИСОК состоит из один диапазон или многие диапазоны, разделенные запятыми. Выбранный ввод написан в том же порядке, что и считывается, и записывается ровно один раз.
Сначала он принимает поле 1, поэтому печатается, а затем поле 2.
Вместо этого используйте awk
:
awk '{ print $2 " " $1}' file.txt
Ответ 2
Вы также можете комбинировать cut
и paste
:
paste <(cut -f2 file.txt) <(cut -f1 file.txt)
через комментарии: можно избежать ошибок и удалить один экземпляр среза, выполнив:
paste file.txt file.txt | cut -f2,3
Ответ 3
используя только оболочку,
while read -r col1 col2
do
echo $col2 $col1
done <"file"
Ответ 4
Вы можете использовать Perl для этого:
perl -ane 'print "$F[1] $F[0]\n"' < file.txt
- -e опция означает выполнение команды после нее
- -n означает чтение строки за строкой (откройте файл, в этом случае STDOUT и переверните строки)
- -a означает разделение таких строк на вектор, называемый @F ( "F" - подобное поле). Perl индексы векторов, начиная с 0, в отличие от разреза, который индексирует поля, начинающиеся с формы 1.
- Вы можете добавить шаблон -F (без пробела между -F и pattern) для использования шаблона в качестве разделителя полей при чтении файла вместо стандартного пробела.
Преимущество работы perl в том, что (если вы знаете Perl), вы можете сделать гораздо больше вычислений на F, чем переупорядочивать столбцы.
Ответ 5
Просто работал над чем-то очень похожим, я не эксперт, но я думал, что буду делиться командами, которые я использовал. У меня было много столбцов csv, из которых мне требовалось только 4 столбца, а затем мне нужно было их переупорядочить.
Мой файл был pipe '|' но это может быть заменено.
LC_ALL=C cut -d$'|' -f1,2,3,8,10 ./file/location.txt | sed -E "s/(.*)\|(.*)\|(.*)\|(.*)\|(.*)/\3\|\5\|\1\|\2\|\4/" > ./newcsv.csv
По общему признанию, это действительно грубо и готово, но оно может быть изменено в соответствии с требованиями!
Ответ 6
Используя join
:
join -t $'\t' -o 1.2,1.1 file.txt file.txt
Заметки:
-
-t $'\t'
В GNU join
к более интуитивно понятному -t '\t'
без $
fails (coreutils v8.28 и более ранние?); это, вероятно, ошибка, что обходной путь, такой как $
должен быть необходим. Смотрите: unix join разделитель char.
-
join
требуется два имени файла, хотя над ним работает только один файл. Используя то же имя дважды фокусы join
в выполнение желаемого действия.
-
Для систем с ограниченными ресурсами join
предлагает меньшую площадь, чем некоторые инструменты, используемые в других ответах:
wc -c $(realpath 'which cut join sed awk perl') | head -n -1
43224 /usr/bin/cut
47320 /usr/bin/join
109840 /bin/sed
658072 /usr/bin/gawk
2093624 /usr/bin/perl
Ответ 7
Я разместил другое решение под этим вопросом, используя короткий Python script, который гораздо удобнее использовать со многими столбцами: fooobar.com/info/63154/...