Extrahieren Sie den Elementbereich vom i-ten Element bis zum j-ten Element und bis zum n-ten Element aus einer Liste

Extrahieren Sie den Elementbereich vom i-ten Element bis zum j-ten Element und bis zum n-ten Element aus einer Liste

In einem Verzeichnis habe ich eine bestimmte Anzahl von Dateien. Das könnten 53 txt-Dateien sein, aber ich könnte auch 123 Dateien haben. Die Dateien haben verschiedene zufällige Namen, aber alle haben den Datei-Handle.txt

Ich kann mit ls eine Liste aller Dateien abrufen und diese in eine Variable einfügen.

list_of_txt_files=$(ls *.txt)

Ich möchte die Liste jedoch in mehrere einzelne Listen aufteilen, wobei jede Liste nur 10 Elemente enthält. Ein Ordner mit 53 TXT-Dateien sollte mir also 6 Listen liefern. Das sind 5 Listen mit 10 Dateinamen und eine 6. Liste mit 3 Dateinamen. Mein Beispiel mit 123 TXT-Dateien in einem Verzeichnis sollte mir 12 Listen mit 10 Dateinamen und eine 13. Liste mit nur 3 Dateinamen liefern.

In meinem Beispiel mit 53 txt-Dateien: Liste Nr. 1 würde die erste bis zur zehnten Datei enthalten, und Liste Nr. 2 würde die elfte bis zur zwanzigsten Datei enthalten und so weiter. Ich habe meine Frage vom i-ten bis zum j-ten Element in einer Liste betitelt, da ich annehme, dass andere Leute eine Liste anders aufteilen möchten. Vielleicht von der ersten bis zur 100. Datei in einem Verzeichnis.

Das ultimative Ziel ist, diese Listen in einer for do-Schleife verwenden zu können und den cat-Befehl zu verwenden, um den Inhalt von zehn Dateien pro Liste in eine Datei pro Satz von zehn Dateien zu schreiben – in meinem Beispiel mit 53 Dateien in einem Verzeichnis würde dies 6 Dateien ergeben. Wobei die ersten 5 Dateien den Inhalt der 50 ursprünglichen txt-Dateien enthalten und die 6. Datei den Inhalt der letzten verbleibenden 3 txt-Dateien.

Ich habe überlegt, den Befehl „head“ oder „tail“ zu verwenden, kann aber nicht ganz herausfinden, wie ich für diese beiden Befehle Bereiche angeben kann.

Antwort1

Auf einer Schale mitArrays, verwenden Sie sie. Sagen Sie mit Bash:

$ touch {01..53}
$ files=(*)
$ echo "${files[@]:0:10}"       
01 02 03 04 05 06 07 08 09 10

$ for ((i = 0 ; i < ${#files[@]} ; i += 10 )) ; do
     echo "${files[@]:i:10}" ; 
     # or
     # cat "${files[@]:i:10}" > set-$(( i / 10 ))
  done
01 02 03 04 05 06 07 08 09 10
11 12 13 14 15 16 17 18 19 20
21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40
41 42 43 44 45 46 47 48 49 50
51 52 53

DerTeilstringerweiterung(Array-Slice) "${files[@]:i:10}"wird zu einer Liste von Wörtern und nicht zu einem einzelnen String erweitert, sodass Sie eine Schleife darüber durchführen können:

for f in "${files[@]:i:10}" ; do
    somecmd "$f"
done

Nichtdo files=$(ls *.txt), das lsist hier völlig überflüssig, es ist sowieso die Shell, die das Platzhaltermuster auswertet. Normalerweise speichern Sie das Platzhaltermuster einfach in einer Variable ( pat=*.txt) und verwenden es (ohne Anführungszeichen), wenn es benötigt wird, oder wenn Sie es in die tatsächlichen Dateinamen erweitern möchten, verwenden Sie echo *.txtanstelle von ls. Für die Handhabung von Dateinamenlisten sind Arrays einfach besser, wenn Sie nicht auf eine einfache POSIX-Shell beschränkt sind.


Zum Teilen einer Liste mit headund tailmüssten Sie etwa Folgendes tun, | head -20 | tail -10um die Zeilen 11 bis 20 zu erhalten. Oder verwenden Sie sed: | sed -n 11,20p.

Antwort2

Mit jeder Bourne-ähnlichen Shell (außer der Bourne-Shell, die nicht auf Positionselemente über zugreifen konnte $9) können Sie Folgendes tun:

set -- *.txt
while [ "$#" -gt 0 ]; do
  something with "$1" ${2+"$2"} ${3+"$3"}... ${10+"${10}"}
  [ "$#" -gt 10 ] || break
  shift 10
done

Mit GNU xargsund Shells mit Unterstützung für Prozesssubstitution:

xargs -n10 -r0a <(printf '%s\0' *.txt) something with

Mit zsh:

files=(*.txt(N))
while (($#files)) {
  something with $files[1,10]
  files[1,10]=()
}

Oder:

autoload -U zargs
xargs -l10 -- *.txt -- something with

zshBeachten Sie auch, dass Sie in den Globs einen Bereich verwenden können :

something with *.txt([1,10])

verwandte Informationen