Odpowiedzi:
-FOpcja wymaga argumentu: -F,na przykład.
Koniec awkskryptu musi być oddzielony znakiem (spacją) z resztą parametrów.
Jeśli separatorem pól jest ,i chcesz go zachować, a liczba kolumn jest stała i mniejsza lub równa 11, spróbuj tego:
awk -F, '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=, "$file"
command file > newfile && mv newfile file. Powiedział, że nowsza wersja GNU awkwspierać w ten sposób: gawk -i inplace '{blah blah}' file.
mv newfile fileciebie możesz użyć cat newfile > file ; rm -f newfile- to zachowuje i-węzeł i uprawnienia file.
mktempzamiast skryptów tymczasowych nazw plików w skryptach. np.tf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
Byłoby krótsze rozwiązanie
awk -F',+' -v OFS=, '{$(NF+1)=$7; $7=""; $0=$0; $1=$1}1' file
Nie jestem pewien, czy ,+będzie działał we wszystkich awkwersjach, ale działa przynajmniej w GNU awk, także w -ctrybie zgodności.
Wyjaśnienie:
$(NF+1)=$7: najpierw dodajemy siódme pole na końcu linii (może być $12=$7w tym przypadku)$7="": w następnym kroku 7. pole jest usuwane (ale otaczające ograniczniki pozostają)$0=$0) traktując wiele przecinków jako separator pól (odbywa się to przez -F',+', tutaj +oznacza jeden lub więcej razy), a także zmienić kolejność bieżącego rekordu, $1=$1aby wymusić przebudowę linii za pomocą wcześniej ustawionego pola wyjściowego separator (ustawiany przez opcję -v OFS=,)1Przykładowe dane wejściowe:
1,2,3,4,5,6,7,8,9,10,11
wynik
1,2,3,4,5,6,8,9,10,11,7
,+powinno działać.
all,ball,call,,,fall→ all,ball,call,fall). (2) $(NF+1)=$7to sprytne podejście. IMHO $0 = $0 OFS $7jest nieco jaśniejszy, ma tylko kilka znaków dłużej i wydaje się, że robi to samo. Czy możesz pomyśleć o sytuacji, w której $0 = $0 OFS $7kod nie działa tak samo jak kod?
$0=$0 OFS $7jest prawdopodobnie identyczny $(NF+1)=$7, ale tylko z resztą kodu niezmienioną, ogólnie nie.
Jeśli drukujesz za pomocą OFS=, więc bez separatora między polami, możesz po prostu zapisać wartość $7zmiennej, ustawić $7puste i wydrukować linię i zmienną bezpośrednio. Nie musisz określać wszystkich pól:
$ cat file
1,2,3,4,5,6,7,8
$ awk -F, -vOFS= '{k=$7; $7=""; print $0,k}' file
12345687
Prawdopodobnie masz na myśli:
awk -F, -v OFS='' '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' "$file"
awknigdy nie widzi pojedynczych cytatów OFS='', prawda? Równie dobrze możesz po prostu pisać OFS=; jest dokładnie tak samo.
Nie specjalnie powiedzieć, że chciał użyć awk, a nie mówią, że chciał użyć edycji w miejscu jak zapewnia sed -i, więc o to sed -iwariant. Zwykle awklepiej jest pracować z kolumnami, ale jest to jeden przypadek, w którym wolę sed, ponieważ naturalnie obsługuje dowolną liczbę kolumn.
MOVECOL=7
N=$((MOVECOL-1))
sed -r -e "s/^(([^,]*,){$N})([^,]*),(.*)/\1\4,\3/" -i test.csv
Wyjaśnienie:
-r wybiera rozszerzone wyrażenia regularne, aby uniknąć mnożenia odwrotnych ukośnikówOczywiście nie będzie to działać z plikami, które ukrywają przecinki w cudzysłowach (lub, co gorsza, unikaj ich), ale awk nie poradzi sobie z tym bez poważnych działań akrobatycznych. Jeśli masz ten problem, lepiej skorzystaj z perlmodułu Text:CSVlub pythonmodułu csv.
Kilka awkwariantów (zakładając, że plik znajduje się w zmiennej $file)
Tutaj możesz przejechać cały kolor, wydrukować za pomocą separatora pól (OFS) i wydrukować terminator rekordów (ORS) na końcu wiersza.
awk -F',' -v OFS=, \
'{for(i=1;i<=NF;i++) if (i!=7) printf "%s",$i OFS; \
printf "%s",$7;printf ORS}' "$file"Tutaj z użyciem wyrażenia regularnego i gensub()funkcji
gawk -F',+' -v OFS=, '{$0=gensub(/\s*\S+/,"",7) OFS $7}1' "$file"
zabijanie na 7 th pola i drukowanie go na końcu linii.
$0 to cały rekord $njest n- tym rekordem NF to liczba pól bieżącej linii OFS separator wyjściowy złożonyORS terminator rekordu wyjściowego1to sztuczka, by powiedzieć awk truei wydrukować default ( $0).Zaktualizuj ...
Prawie zapominam, że możliwe jest przesunięcie wszystkich kolumn po siódmej .
awk -F',' -v OFS=, '{tmp=$7; for(i=7;i<=NF;i++) $i=$(i+1); $NF=tmp}1 ' "$file"
OFS $7byłby bardziej solidny niż "," $7. (2) Uważam, że ", " $7jest to złe, o ile pytanie wskazuje, że OP nie chce spacji po przecinkach. (A jeśli dane wejściowe miałyby spacje po przecinkach, wtedy $7już zaczynałyby się spacją, a ty dodawalibyśmy dodatkową.)
OFS $7, że nie tylko bardziej solidny, ale nawet bardziej ogólny ( „pośpiech czyni marnotrawstwo” )
^Wskazuje część konkretnego polecenia gdzie napotkał błąd.