J'ai un fichier ASCII contenant les chemins de fichiers que j'ai lu en exécutant:
while read p; do echo $p; done < filelist.txt
Le fichier contient des chemins de fichiers avec le motif suivant:
./first/example1/path
./second/example1/path
./third/example2/path
Comment obtenir une partie spécifique de la chaîne de chemin d'accès (de /
à /
), par exemple J'ai besoin d'un résultat qui imprime:
first
second
third
et aussi
example1
example1
example2
Je suis sûr qu'il existe un moyen de le faire en utilisant des expressions régulières et sed
, mais je ne le connais pas bien.
Utilisez cut
:
$ cat filelist.txt
./first/example1/path
./second/example1/path
./third/example2/path
$ cut -d/ -f2 filelist.txt
first
second
third
$ cut -d/ -f3 filelist.txt
example1
example1
example2
-d/
définit le délimiteur de colonne sur /
et le -f2
sélectionne la deuxième colonne.
Vous pouvez bien sûr aussi utiliser des variables Bash au lieu d'un nom de fichier ou transmettre des données dans la commande cut
:
cut -d/ -f3 $MyVariable
echo ./another/example/path | cut -d/ -f3
Vous pouvez le faire directement dans votre commande read
, à l’aide de la variable IFS
, par exemple.
$ while IFS=/ read -r p1 p2 p3 r; do echo "$p2"; done < filelist.txt
first
second
third
Vous pouvez utiliser awk
name__
pilot6@Pilot6:~$ cat filelist.txt
./first/example1/path
./second/example1/path
./third/example2/path
pilot6@Pilot6:~$ awk -F "/" '{print $2}' filelist.txt
first
second
third
pilot6@Pilot6:~$ awk -F "/" '{print $3}' filelist.txt
example1
example1
example2
Si nous voulons n'importe quel élément du chemin, il est préférable d'utiliser quelque chose qui peut diviser une chaîne en champs, tel que awk , cut , python , ou Perl . Cependant, bash peut également effectuer le travail avec la substitution de paramètres, en utilisant le remplacement de modèle et en jetant le tout dans un tableau.
$> echo ${FILE//\//\ }
sys class backlight intel_backlight brightness
$> ARRAY=( ${FILE//\//" " } )
$> echo ${ARRAY[2]}
backlight
$> FILE="./dir1/dir2/file.txt"
$> ARRAY=( ${FILE//\/" "} )
$> echo ${ARRAY[@]}
. dir1 dir2 file.txt
$> echo ${ARRAY[1]}
dir1
Nous avons maintenant un tableau d’articles créé à partir du chemin. Notez que si le chemin contient des espaces, il peut être nécessaire de modifier le séparateur de champ interne IFS
name__.
Bash et cut
sont la voie à suivre, mais une alternative utilisant Perl:
Perl -F/ -lane 'print(@F[1])' filelist.txt
pour le deuxième champ /
- délimité et
Perl -F/ -lane 'print(@F[2])' filelist.txt
pour le troisième champ /
- délimité.
-l
: active le traitement de fin de ligne automatique. Il a deux effets distincts. Premièrement, il chomps automatiquement $/(le séparateur d'enregistrement d'entrée) lorsqu'il est utilisé avec -n ou -p. Deuxièmement, il attribue à $\(le séparateur d'enregistrement de sortie) la valeur d'octnum afin que toutes les instructions d'impression ajoutent ce séparateur. Si octnum est omis, définit $\sur la valeur actuelle de $ /.-a
: active le mode autosplit lorsqu'il est utilisé avec un -n ou -p. Une commande de fractionnement implicite dans le tableau @F est effectuée en premier dans la boucle while implicite produite par -n ou -p.-n
: Perl assume la boucle suivante autour de votre programme, ce qui le rend itératif sur les arguments de nom de fichier un peu comme sed -n ou awk:
LINE:
while (<>) {
... # your program goes here
}
-e
: peut être utilisé pour entrer une ligne de programme;
print(@F[N])
: affiche le Nième champ.% cat filelist.txt
./first/example1/path
./second/example1/path
./third/example2/path
% Perl -F/ -lane 'print(@F[1])' filelist.txt
first
second
third
% Perl -F/ -lane 'print(@F[2])' filelist.txt
example1
example1
example2