Una domanda su Awk


9

Ok, poiché questa è una domanda complessa, la spiegherò chiaramente. Ho un contenuto di file mostrato come di seguito:

$ Cat File1 
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}

L'output che voglio

-Cool MNB +  POP ;
-Cool MNB  + POP ;
-Cool MNB  + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD +POP ;

In primo luogo provo a estrarre l'ultima colonna dal File1e stamparlo da sed 's/[{}//g' File1 > File3

Dopo di che copio l'intero contenuto di File1un nuovoFile4

cp File1 File4

Dopodiché sostituisco i dati all'interno di File4con i File3dati (significa che i dati senza parentesi " File1un'ultima colonna quella")

awk 'FNR==NR{a[NR]=$1;next}{$5=a[FNR]}1' File3 File4 >>File5 

L'output dovrebbe essere così

ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP MNB
ABC Cool Lol POP TBMKF
ABC Cool Lol POP YUKER
ABC Cool Lol POP EFEFVD

Alla fine ci provo

awk -F " '{print - $2,$5 +,$4 ";"}‘ File5

Ma il risultato non è emerso come mostrato come voglio, solo i dati simili MNB sono tutti elencati in basso, altri non sono stati mostrati (File dati dell'ultima colonna),


Stai usando gnu awk?
123

non sono sicuro di cosa intendi. Ma sono solo un nuovo principiante per aver toccato Awk. Questo è il compito che devo fare, faccio del mio meglio per fare lentamente un passo in avanti per fare ciò in base alla mia comprensione di Awk.
heng960407,

1
tipo awk --version, qual è il risultato?
123

2
Per favore cambia il tuo titolo in qualcosa di più specifico per il tuo problema. Ciò renderà più facile per gli altri che hanno domande simili in futuro trovarlo. Al momento "Una domanda su Awk" è molto generale.
Tom Fenech,

Risposte:


16

Non so perché stai copiando le cose a destra e a sinistra. La cosa semplice è

awk '{print "-" $2, substr($5,2,length($5)-2), "+", $4, ";"}' File1

Ho messo -all'inizio e ;poi alla fine.

Tra una stampa e l'altra

  • $2 perché lo vogliamo così com'è.
  • una sottostringa di $5, che è la stringa senza il primo e l'ultimo carattere. Saltiamo il primo personaggio iniziando dalla posizione 2 (awk è sempre stato strano a tale proposito) e tralasciamo l'ultimo carattere selezionando solo una sottostringa che è più corta di due caratteri rispetto all'originale$5
  • il +perché lo vogliamo
  • e poi $4

Tuttavia, non sono sicuro che tutte queste funzioni di stringa siano specifiche di GNU awk.


substr(string, 2)restituisce la sottostringa a partire dal secondo carattere, come cut -c2-, tail -n +2, sed '2,$'... Cosa c'è di strano?
Stéphane Chazelas,

3
Questo comando è standard e funzionerebbe persino con l'originale awkdegli anni '70.
Stéphane Chazelas,

@ StéphaneChazelas: Ah, ti stavo aspettando :-) Di solito iniziamo a contare su 0, il che significa che l'indice 2 è la terza posizione, ma qui la seconda posizione è all'indice 2. Grazie per aver chiarito la restante domanda GNU.
Bananguin,

@Bananguin, nella shell e nei programmi di utilità Unix, come mostrato nei pochi esempi precedenti, iniziamo da 1, non 0. Le eccezioni più importanti sono gli array di ksh e $ {var: offset} (entrambi copiati da bash). Tutti gli altri array di shell iniziano da 1. Vedi anche C'è un motivo per cui il primo elemento di un array Zsh è indicizzato da 1 invece di 0?
Stéphane Chazelas,

7

Con sed

sed '
    s/\S\+\s/-/
    s/\(\S\+\s\)\{2\}{\(\S\+\)}/\2 + \1;/
    ' File1

E variazione imbarazzante

awk -F"[[:blank:]{}]+" '{print "-" $2, $5, "+", $4}' ORS=" ;\n" File1

6

Semplice lavoro TXR :

$ txr -c '@(repeat)
@a @b @c @d {@e}
@(do (put-line `-@b @e + @d ;`))
@(end)' -
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {MNB}
ABC Cool Lol POP {TBMKF}
ABC Cool Lol POP {YUKER}
ABC Cool Lol POP {EFEFVD}
[Ctrl-D][Enter]
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool MNB + POP ;
-Cool TBMKF + POP ;
-Cool YUKER + POP ;
-Cool EFEFVD + POP ;

Utilizzo della macro awk di TXR Lisp per traslitterare la soluzione Awk:

 txr -e '(awk (t (prn `-@[f 1] @{[f 4] [1..-1]} + @[f 3] ;`)))'

I campi sono fnell'elenco e l'indicizzazione è basata su zero.


1
+1 per il look più brillante e cristallino! Quella lingua DEVE competere in pcg (codice di programmazione golf)
Archemar,

@Archemar TXR non compete molto nel golf perché ci sono linguaggi specializzati progettati per quello che fanno cose come assegnare funzioni ai singoli personaggi, che possono quindi essere uniti per ottenere la composizione.
Kaz,

@Archemar Inserisci un commento
Kaz

1
@Kaz Esiste un tutorial TXR da qualche parte? La pagina man sembra piuttosto vasta. Come si comporta rispetto a awk?
bli

1
@bli GNU Awk è qualcosa di almeno 30 volte più veloce nel campo di base che si divide in un file di grandi dimensioni rispetto alla macro awk TXR, che contiene circa 220 righe di codice interpretato , incluso il ciclo generale per l'elaborazione delle fonti di input in record e campi.
Kaz,

3

L'uso di awk è più semplice quando i $1,$2,...campi contengono già le stringhe esatte con cui vuoi lavorare. Il separatore di campo, se contiene più di un carattere, viene interpretato come un'espressione regolare. Non è necessario eseguire alcuna ricerca e sostituzione o operazioni di sottostringa per eliminare le {parentesi graffe}. Li contiamo solo come parte del delimitatore.

awk -F'[ {}]+' '{printf("-%s %s + %s ;\n", $2, $5, $4)}'

L'uso di printfinvece di printrende anche un po 'più semplice vedere come verrà formattata la stringa, ma se si desidera avere print "-"$2,$5" + "$4";"invece di printf("-%s %s + %s ;\n", $2, $5, $4), questa è un'opzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.