Bash cat alla filer i en mapp till nya filer

Permalänk
Medlem

Bash cat alla filer i en mapp till nya filer

För det första, jag är nybörjade på Bash.

Jag vill göra ett Bash script som cat innehållet från alla filer i en mapp, en efter en, till nya filer i samma mapp. Filerna ska heta file0,1,2,3 osv. En ny fil för varje cat'ad fil.

De nya filerna mitt script cat'ar till blir dock tomma. Varför? (filerna jag cat från är INTE tomma)

Mitt script:

#!/bin/bash
count=0
cd /home/bjorn/Desktop/Rawmail2/
for i in *; do
cat "${i}" > file${count}.txt `echo "${i}" | awk -F. '{print $2}'`
((++count))
done

Visa signatur

💻 ROG Maximus XI Hero | i9 9900K | Corsair H115i | Samsung 960 PRO 512GB M.2 | Samsung 970 PRO 1TB M.2 | GTX 1080Ti FTW3 | Corsair 32GB (2x16GB) DDR4 3200MHz | EVGA Supernova G2 750W
📺 Dell Alienware AW2723DF 1440p 280 Hz | Acer XB271HU 1440p 165Hz
🎧 Schiit stack: Magni 3+ AMP | Modi 3 DAC | Sennheiser HD600 | HD800

Permalänk
Hedersmedlem
Skrivet av Asce:

För det första, jag är nybörjade på Bash.

Jag vill göra ett Bash script som cat innehållet från alla filer i en mapp, en efter en, till nya filer i samma mapp. Filerna ska heta file0,1,2,3 osv. En ny fil för varje cat'ad fil.

De nya filerna mitt script cat'ar till blir dock tomma. Varför? (filerna jag cat från är INTE tomma)

Mitt script:

#!/bin/bash
count=0
cd /home/bjorn/Desktop/Rawmail2/
for i in *; do
cat "${i}" > file${count}.txt `echo "${i}" | awk -F. '{print $2}'`
((++count))
done

Till att börja med: varför inte bara använda `cp` och kopiera filerna?

Vad gäller

cat "${i}" > file${count}.txt `echo "${i}" | awk -F. '{print $2}'`

så gör den raden nog inte vad som är tänkt. `cat "${i}"` spottar ut filen till stdout och `> file${count}.txt` skickar detta till en korrekt namngiven fil. Vad tänker du att `echo "${i}" | awk -F. '{print $2}'`` ska göra? Dels så verkar det bara vara ett omständligt sätt att skriva ut filändelsen (`${i##*.}` ger filändelsen direkt i shell script, vilket är en delmängd av Bash), som också kommer fela ifall sökvägen eller filnamnet i sig innehåller en extra punkt, och dels så kommer resultatet som det står just nu bara ges som ett extra argument till `cat`, vilket kanske är förvånande om man inte är med på hur `>`-operatorn fungerar; det spelar faktiskt ingen roll var `>` operatorn skrivs i ditt ovanstående kommando (den hade kunnat stå först, i mitten eller sist, så länge som den följs av det filnamn den ska skicka output till). Operatorn tar också bara ett argument här, dvs filen du vill skriva till, så `txt` kommer alltså "lämnas kvar" till `cat`.

I praktiken så kommer varje loop ge en kommandorad ekvivalent med:

cat originalfil1.txt txt > file0.txt

Förutom att du troligen inte vill ha med argumentet `txt` till `cat` så ställer det återigen frågan om varför du inte bara använder `cp` direkt .

Man kan också notera att det inte finns någon egentlig anledning att skriva detta specifikt i Bash, utan "vanligt" shell script duger lika väl, men den triviala modifikationen att ändra `(count++)` till `count=$((count+1))` (och shebangen från `#!/bin/bash` till `#!/bin/sh`, då).

Filerna borde inte bli tomma i vilket fall, utan snarare bara ge ett felmeddelande, men det kan vara bra att börja nysta i vad som överhuvudtaget händer i skriptet.

Notera också att du kan lägga till `set -x` på en ensam rad högst upp (efter shebang, dock) i ett skript för att få diagnostisk output när skriptet körs.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.

Permalänk
Medlem

Det finns en speciell anledning till varför jag inte kör med cp.

Filerna jag catar är .eml filer, email filer. Jag granskar dessa filer i source format/råformat direkt i en mailklient för att få ut viss header-data från dem som jag är intresserad av. Det tar rätt lång tid när man ska granska många filer på detta sätt. Så jag vill konvertera dem alla till rent text så jag kan öppna dem direkt. Om jag endast kopierar/döper om en sådan fil till en .txt fil så kan jag inte granska rådatan genom att bara öppna filen som den är, funkar inte.

Men om jag kör cat på den (.eml filen) och skickat output från det till en fil så kan jag bara kolla den filen direkt utan att behöva öppna den i en mailklient med stöd för .eml-filer.

Visa signatur

💻 ROG Maximus XI Hero | i9 9900K | Corsair H115i | Samsung 960 PRO 512GB M.2 | Samsung 970 PRO 1TB M.2 | GTX 1080Ti FTW3 | Corsair 32GB (2x16GB) DDR4 3200MHz | EVGA Supernova G2 750W
📺 Dell Alienware AW2723DF 1440p 280 Hz | Acer XB271HU 1440p 165Hz
🎧 Schiit stack: Magni 3+ AMP | Modi 3 DAC | Sennheiser HD600 | HD800

Permalänk
Hedersmedlem
Skrivet av Asce:

Det finns en speciell anledning till varför jag inte kör med cp.

Filerna jag catar är .eml filer, email filer. Jag granskar dessa filer i source format/råformat direkt i en mailklient för att få ut viss header-data från dem som jag är intresserad av. Det tar rätt lång tid när man ska granska många filer på detta sätt. Så jag vill konvertera dem alla till rent text så jag kan öppna dem direkt. Om jag endast kopierar/döper om en sådan fil till en .txt fil så kan jag inte granska rådatan genom att bara öppna filen som den är, funkar inte.

Men om jag kör cat på den (.eml filen) och skickat output från det till en fil så kan jag bara kolla den filen direkt utan att behöva öppna den i en mailklient med stöd för .eml-filer.

`cat` genomför ingen konvertering av indata när de omdirigeras till en fil. Snabbdemonstration med en fil med binärt innehåll:

$ cat förlaga > kopia $ diff -s förlaga kopia Files förlaga and kopia are identical $ md5sum förlaga kopia 5312a3bf315def1a215ff5eca5e511a1 förlaga 5312a3bf315def1a215ff5eca5e511a1 kopia

Det måste vara något annat steg du menar.

Visa signatur

Nu med kortare användarnamn, men fortfarande bedövande långa inlägg.