У меня есть файл в следующем формате
Столбец1 Столбец2 ул1 1 ул2 2 ул3 3
Я хочу, чтобы столбцы переставили. Я пробовал команду ниже
вырезать -f2,1 file.txt
Команда не меняет порядок столбцов. Есть идеи, почему это не работает?
Спасибо.
Для cut(1)
страницы руководства :
Используйте один и только один из -b, -c или -f. Каждый СПИСОК состоит из одного диапазона или нескольких диапазонов, разделенных запятыми. Выбранный ввод записывается в том же порядке, в котором он читается, и записывается ровно один раз.
Сначала он достигает поля 1, так что оно печатается, а затем поле 2.
awk
Вместо этого используйте :
awk '{ print $2 " " $1}' file.txt
cut
что эта интуитивно понятная команда переупорядочения не поддерживает. В любом случае, еще один совет: вы можете использоватьawk
's-FS
и-OFS
options для использования настраиваемых разделителей полей ввода и вывода (например,-d
и--output-delimiter
дляcut
).FS
это вариант,OFS
это переменная. egawk -v OFS=";" -F"\t" '{print $2,$1}'
| sed 's/\r//' |
awk
awk '{print $4 "\t" $2 "\t" $6 "\t" $7}' file
Вы также можете комбинировать
cut
иpaste
:через комментарии: можно избежать башизмов и удалить один экземпляр cut, выполнив:
источник
cut
отлично работает для столбцов переменной длины, если у вас есть уникальный разделитель столбцов.bash
измов и удалить один экземплярcut
, выполнив следующие действия:paste file.txt file.txt | cut -f2,3
используя только оболочку,
источник
"$col2"
и"$col1"
- в данных могут быть метасимволы оболочки или другие махинации.Для этого можно использовать Perl:
Преимущество использования Perl заключается в том, что (если вы знаете Perl) вы можете выполнять на F гораздо больше вычислений, чем переупорядочивать столбцы.
источник
perl -ae print
работаетcat
для меняИспользование
join
:Ноты:
-t $'\t'
В GNUjoin
более интуитивным-t '\t'
без$
сбоя ( Coreutils v8.28 и раньше?); вероятно, это ошибка, требующая обходного пути$
. См .: unix join separator char .join
требуется два имени файла, даже если идет работа только с одним файлом. Использование одного и того же имени дважды помогаетjoin
выполнить желаемое действие.Для систем с небольшими ресурсами
join
предлагает меньшую площадь, чем некоторые инструменты, используемые в других ответах:источник
Просто работал над чем-то очень похожим, я не эксперт, но я подумал, что поделюсь командами, которые использовал. У меня был многоколоночный csv, из которого мне потребовалось всего 4 столбца, а затем мне нужно было их переупорядочить.
Мой файл был трубкой '|' с разделителями, но это можно поменять местами.
По общему признанию, он действительно груб и готов, но его можно настроить под себя!
источник
Используя sed
Используйте sed с вложенными подвыражениями базового регулярного выражения для захвата и изменения порядка содержимого столбца. Этот подход лучше всего подходит, когда количество сокращений для изменения порядка столбцов ограничено, как в этом случае.
Основная идея состоит в том, чтобы окружить интересные части шаблона поиска символами
\(
и\)
, которые могут быть воспроизведены в шаблоне замены,\#
где где#
представляет собой последовательную позицию части выражения в шаблоне поиска.Например:
выходы:
Текст вне части выражения сканируется, но не сохраняется для воспроизведения в строке замены.
Хотя в вопросе не обсуждались столбцы фиксированной ширины, мы обсудим это здесь, поскольку это достойная мера любого предложенного решения. Для простоты предположим, что файл разделен пробелами, хотя решение может быть расширено для других разделителей.
Свертывающиеся пространства
Чтобы проиллюстрировать простейшее использование, давайте предположим, что несколько пробелов могут быть свернуты в отдельные пробелы, а значения второго столбца заканчиваются EOL (а не заполняются пробелами).
Файл:
Transform:
Сохранение ширины столбца
Давайте теперь расширим этот метод до файла со столбцами постоянной ширины, разрешив столбцам иметь разную ширину.
Файл:
Transform:
Наконец, хотя в примере вопроса нет строк неравной длины, это выражение sed поддерживает этот случай.
Файл:
Transform:
Сравнение с другими методами изменения порядка столбцов в оболочке
Удивительно для инструмента обработки файлов, но awk не очень хорошо подходит для вырезания от поля до конца записи. В sed это можно сделать с помощью регулярных выражений, например,
\(xxx.*$\)
гдеxxx
- выражение, соответствующее столбцу.Использование вставки и вырезания подоболочек становится сложной задачей при реализации внутри сценариев оболочки. Код, который работает из командной строки, не может быть проанализирован, когда он помещен в сценарий оболочки. По крайней мере, это был мой опыт (который подтолкнул меня к такому подходу).
источник
Расширяя ответ от @Met, также используя Perl:
Если ввод и вывод разделены табуляцией:
Если ввод и вывод разделены пробелами:
Здесь
-e
Perl сообщает Perl искать код в строке, а не в отдельном файле сценария,-n
считывает ввод по одной строке за раз,-l
удаляет разделитель входных записей (\n
на * NIX) после чтения строки (аналогичноchomp
) и добавляет вывод разделитель записей (\n
на * NIX) для каждогоprint
,-a
разбивает строку ввода на пробелы в массив@F
,-F'\t'
в сочетании с-a
разбивает строку ввода на табуляции, вместо пробелов на массив@F
.@F[1, 0]
- это массив, состоящий из 2-го и 1-го элементов массива@F
в этом порядке. Помните, что массивы в Perl имеют нулевой индекс, а поляcut
- 1. Таким образом, поля в@F[0, 1]
- это те же поля, что и вcut -f1,2
.Обратите внимание, что такая нотация позволяет более гибко манипулировать вводом, чем в некоторых других ответах, опубликованных выше (которые подходят для простой задачи). Например:
источник