Відповіді:
Для -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
- це зберігає inode та дозволи 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
та надрукувати за замовчуванням ( $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
, не тільки більш надійний, але ще загальніший ( "поспіх робить сміття" )
^
Вказує на певну частину команди , де була виявлена помилка.