GNU/Linux >> Tutoriels Linux >  >> Linux

Extraire les chemins manquants du tableau bash de chemins

Vous avez déjà découvert la raison immédiate pour laquelle votre code n'a pas fait ce que vous attendiez :les erreurs de ls sont signalés à stderr (comme suggéré par POSIX), qui n'est pas capturé en tant qu'entrée par le tube. Vous avez donc obtenu un mélange de sortie normale (qui est passée inchangée par votre sed instructions) et stderr (qui les contournait). Je ne sais pas pourquoi votre ls la sortie a changé entre les appels ; la redirection de stdout vers /dev/null devrait avoir pour effet de supprimer tous les "chemins normaux" (chemins existants) de la sortie. Le correctif n'est pas pour pousser stderr dans stdout, cependant.

Post-traitement de la sortie de ls est une idée dangereuse si vous voulez un script fiable. Un bon article sur le sujet est "Why you should not parse the output of ls(1)", disponible sur le site wooledge.org. Une séance de questions/réponses approfondie sur le site Unix et Linux traite de certains problèmes :pourquoi pas analyser ls (et que faire à la place) ?. Le résultat est que les noms de fichiers UNIX peuvent contenir presque n'importe quel caractère, y compris les espaces, les tabulations, les retours à la ligne, les guillemets simples, les guillemets doubles, les guillemets simples échappés, etc. ! Pour quelques exemples rapides, considérez les répertoires portant ces noms, qui sont tous parfaitement légaux :

  • "Aucun fichier de ce type" (mkdir "No such file" )
  • "ls :impossible d'accéder à 'foo' :aucun fichier ou répertoire de ce type" (mkdir "ls: cannot access 'foo': No such file or directory" )
  • "répertoire

    avec

    intégré

    retour à la ligne" (mkdir $'directory\nwith\nembedded\newlines' )

Le premier est un répertoire innocent qui est capturé à tort (depuis stdout) par le grep . Le second est également capturé à tort, mais ensuite mutilé dans un chemin complètement différent - qui peut exister ou non ! -- par le sed déclarations. Le troisième est un exemple de ce qui se passe lorsque vous transmettez la sortie de ls dans des programmes axés sur la ligne ; si le répertoire n'existe pas, ls le dira sur plus d'une ligne, ce qui est probablement la raison pour laquelle vous vous êtes retrouvé avec deux sed distincts déclarations !

Pour distinguer les "bons chemins" - ceux qui existent et sont lisibles - des "mauvais chemins", je suggérerais de boucler sur le tableau et de créer de nouveaux tableaux de chacun.

for p in "${paths[@]}"
do
  if [ -r "$p" ]
  then
    goodpaths+=("$p")
  else
    badpaths+=("$p")
  fi
done

Vous pouvez ensuite faire ce que vous voulez avec chaque ensemble :

printf 'Good path: -->%s<--\n' "${goodpaths[@]}"
echo
printf 'Bad path: -->%s<--\n' "${badpaths[@]}"

Linux
  1. Quel terminal est le meilleur :Bash vs Zsh

  2. Analyser un champ d'un tableau Json dans un tableau Bash ?

  3. Est-il possible dans Bash de commencer à lire un fichier à partir d'un décalage arbitraire du nombre d'octets ?

  4. Exécuter le script bash à partir de l'URL

  5. démarrer apachectl à partir de bash

Tableaux bash

Tableau associatif dans Bash

Tableau dans Bash introuvable

extraire le temps moyen de ping -c

Convertir une chaîne de texte en bash en tableau

Script bash Linux pour extraire l'adresse IP