Jak policzyć, ile razy określony znak pojawia się w pliku?

18

Na przykład chcemy policzyć wszystkie "znaki quote ( ); martwimy się tylko, jeśli pliki zawierają więcej ofert niż powinny.

Na przykład:

cluster-env,"manage_dirs_on_root","true"
cluster-env,"one_dir_per_partition","false"
cluster-env,"override_uid","true"
cluster-env,"recovery_enabled","false"

oczekiwane rezultaty:

16

Yael
źródło
Zobacz Najłatwiejszy sposób na znalezienie brakującego cytatu w skrypcie bash? jeśli to naprawdę chcesz wiedzieć.
G-Man mówi „Reinstate Monica”

Odpowiedzi:

26

Możesz łączyć tr(tłumaczyć lub usuwać znaki) z wc(liczyć słowa, linie, znaki):

tr -cd '"' < yourfile.cfg | wc -c

( -dusuń wszystkie znaki z cdopełnienia ", a następnie policz znaki c).

Ulrich Schwarz
źródło
20

podejście grep :

grep -o '"' file | wc -l
16 
  • -o - wyświetla tylko dopasowane podciągi

Lub z pojedynczym gawk :

awk -v RS='' -v FPAT='"' '{print NF}' file
16
  • RS='' - pusty separator rekordów (zamiast nowego wiersza)

  • FPAT='"' - wartość pola definiującego wzór

Roman Perekhrest
źródło
-ojest niestandardowym rozszerzeniem GNU do standardowego grepnarzędzia. Nie wspomniano o tym w dokumentacji POSIXgrep .
Andrew Henle,
4

Jeśli dwa wiersze w pliku mają nieparzystą liczbę podwójnych cudzysłowów, łączna suma podwójnych cudzysłowów będzie parzysta i nie wykryjesz niezrównoważonych cudzysłowów (zakładam, że tak naprawdę chciałbyś to zrobić, ale mogę się mylić ).

Ten awkskrypt zgłasza każdą linię w linii wejściowej, która zawiera nieparzystą liczbę cudzysłowów:

awk -F'"' 'NF % 2 == 0 { printf("Line %d has odd quoting: %s\n", NR, $0) }'

Możemy ustawić separator pól ( FS), aby "z -F'"'co oznacza, że jeśli linia ma numer nawet pól to ma dziwnych cytatów. NFjest liczbą pól w ostatnim rekordzie i NRjest liczbą porządkową bieżącego rekordu („numer linii”).

Biorąc pod uwagę następujące dane wejściowe:

$ cat file
cluster-env,"manage_dirs_on_root","true"
cluster-env,"one_dir_per_partition","false"
cluster-env,override_uid","true"
cluster-env,recovery_enabled","false"

dostajemy

$ awk -F'"' 'NF % 2 == 0 { printf("Line %d has odd quoting: %s\n", NR, $0) }' file
Line 3 has odd quoting: cluster-env,override_uid","true"
Line 4 has odd quoting: cluster-env,recovery_enabled","false"

Coś jak

$ grep -o '"' | wc -l

zwróci „14” dla tego pliku.

Kusalananda
źródło
2

Kolejne pojedyncze gawkpodejście:

awk -v RS=\" 'END{print NR-1}'
αғsнιη
źródło
2

Czysta BASH:

var="$(< file.txt)"
tmp="${var//[^\"]/}"
echo ${#tmp}
Thunderbeef
źródło
Czy tmptablica? Jeśli tak, czy tmpjest to tablica czego?
Tim
@Tim, no. tmpw tym fragmencie znajduje się normalna zmienna powłoki. Głosuję za odrzuceniem tej odpowiedzi, ponieważ liczy się to, ile razy znak pojawia się w zmiennej ( var), a nie w pliku, jak określono w pytaniu.
Wildcard
0

próbować:

grep -0 '"' File -c

nie zadziała to jednak, jeśli dwa lub więcej znaków w tej samej linii. Będą liczone jako jeden znak

Abdulkarim Malkadi
źródło
1
Witamy w U&L! To wydaje się nie odpowiadać na pytanie, ponieważ będzie liczyć wiersze zamiast znaków. Zdecydowanie zachęca się do pisania skutecznych odpowiedzi na temat U&L - patrz Odpowiedzi w centrum pomocy. Możesz poprawić ten.
fra-san
0

plik grep -oF '"| wc -l

-F oznacza stały ciąg

shinek
źródło
Jest to to samo, co pierwsza część odpowiedzi RomanPerekhrest, z tym wyjątkiem, że dodałeś -Fflagę, która nie jest tutaj potrzebna.
G-Man mówi „Reinstate Monica”
0

Ekscentryczna metoda podwójnego GNU grep :

grep -o \" file | grep -c .
agc
źródło