Ответы:
-F
Вариант нужен аргумент: -F,
например.
Конец awk
скрипта должен быть отделен (пробел) с остальными параметрами.
Если разделитель полей установлен ,
и вы хотите его сохранить, а номер столбца постоянен и меньше или равен 11, попробуйте следующее:
awk -F, '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=, "$file"
command file > newfile && mv newfile file
. Тем не менее, новая версия GNU awk
для поддержки этого: gawk -i inplace '{blah blah}' file
.
mv newfile file
вы могли использовать cat newfile > file ; rm -f newfile
- это сохраняет индекс и права доступа file
.
mktemp
а не жестко кодировать временные имена файлов в сценарии. напримерtf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
Более короткое решение будет
awk -F',+' -v OFS=, '{$(NF+1)=$7; $7=""; $0=$0; $1=$1}1' file
Я не уверен, ,+
будет ли работать во всех awk
версиях, но работает, по крайней мере, в GNU awk, также с -c
режимом совместимости.
Объяснение:
$(NF+1)=$7
: сначала мы добавляем 7-е поле в конец строки (может быть $12=$7
в этом случае)$7=""
: на следующем шаге 7-е поле стирается (но окружающие разделители остаются)$0=$0
), обрабатывая несколько запятых как разделитель полей (это делается через -F',+'
, здесь +
означает один или несколько раз), а также переупорядочить текущую запись через, $1=$1
чтобы принудительно перестроить строку, используя ранее установленное поле вывода разделитель (устанавливается опцией -v OFS=,
)1
Пример ввода:
1,2,3,4,5,6,7,8,9,10,11
выход
1,2,3,4,5,6,8,9,10,11,7
,+
должно работать.
all,ball,call,,,fall
→ all,ball,call,fall
). (2) $(NF+1)=$7
это умный подход. ИМХО, $0 = $0 OFS $7
немного понятнее, всего пара символов длиннее, и, похоже, делает то же самое. Можете ли вы вспомнить ситуацию, в которой $0 = $0 OFS $7
не происходит то же самое, что ваш код?
$0=$0 OFS $7
вероятно идентичен $(NF+1)=$7
, но только с остальной частью кода без изменений, но не в целом.
Если вы печатаете с OFS=
, то есть без разделителя между полями, вы можете просто сохранить значение $7
в переменной, установить $7
пустое значение и напечатать строку и переменную напрямую. Вам не нужно указывать все поля:
$ cat file
1,2,3,4,5,6,7,8
$ awk -F, -vOFS= '{k=$7; $7=""; print $0,k}' file
12345687
Вы, вероятно, имеете в виду:
awk -F, -v OFS='' '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' "$file"
awk
никогда не видите одинарные кавычки OFS=''
, верно? Вы также можете просто напечатать OFS=
; это точно так же.
Вы специально не сказать , что вы хотите использовать AWK, и вы же говорите , что вы хотите использовать на месте монтажа , как предусмотрено sed -i
, так вот sed -i
вариант. Обычно awk
лучше работать со столбцами, но это один из тех случаев, когда я предпочитаю sed
, потому что он, естественно, обрабатывает произвольное количество столбцов.
MOVECOL=7
N=$((MOVECOL-1))
sed -r -e "s/^(([^,]*,){$N})([^,]*),(.*)/\1\4,\3/" -i test.csv
Объяснение:
-r
выбирает расширенные регулярные выражения, поэтому мы избегаем большого количества обратной косой чертыКонечно, это не будет работать с файлами, которые скрывают запятые в кавычках (или, что еще хуже, избегают их), но awk не справится и без серьезной акробатики. Если у вас есть эта проблема, вам лучше использовать perl
модуль Text:CSV
или python
модуль csv
.
Пара awk
вариантов (при условии, что ваш файл находится внутри переменной $file
)
Здесь вы можете выполнить цикл для всех столбцов, распечатать с разделителем полей (OFS) и распечатать терминатор записи (ORS) в конце строки.
awk -F',' -v OFS=, \
'{for(i=1;i<=NF;i++) if (i!=7) printf "%s",$i OFS; \
printf "%s",$7;printf ORS}' "$file"
Здесь с использованием регулярных выражений и gensub()
функции
gawk -F',+' -v OFS=, '{$0=gensub(/\s*\S+/,"",7) OFS $7}1' "$file"
убить 7- е поле и распечатать его в конце строки.
$0
это целая запись $n
это n- я запись NF
количество полей текущей строки OFS
выходной полевой разделительORS
терминатор выходной записи1
это трюк, чтобы сказать awk true
и напечатать default ( $0
).Обновить ...
Я почти забыла, что можно сдвинуть все столбцы после 7- го .
awk -F',' -v OFS=, '{tmp=$7; for(i=7;i<=NF;i++) $i=$(i+1); $NF=tmp}1 ' "$file"
OFS $7
будет более надежным, чем "," $7
. (2) Я считаю, что ", " $7
это неправильно, поскольку вопрос указывает, что ОП не хочет пробелов после запятых. (И если бы во входных данных были пробелы после запятых, то $7
они уже начинались бы с пробела, и вы бы добавили дополнительный.)
OFS $7
, не только более надежное, но и более общее ( «спешка тратит впустую» )
^
Указывает на определенную часть команды , где была обнаружена ошибка.