Jamais travaillé avec des scripts shell auparavant, mais j'en ai besoin dans ma tâche actuelle.
Je dois donc exécuter une commande qui renvoie une sortie comme celle-ci:

    awd54a7w6ds54awd47awd refs/heads/SomeInfo1  
    awdafawe23413f13a3r3r refs/heads/SomeInfo2 
    a8wd5a8w5da78d6asawd7 refs/heads/SomeInfo3 
    g9reh9wrg69egs7ef987e refs/heads/SomeInfo4 

Et j'ai besoin de boucler sur chaque ligne de sortie obtenir uniquement la partie "SomeInfo" et l'écrire dans un fichier dans un format comme celui-ci:

    ["SomeInfo1","SomeInfo2","SomeInfo3"]

J'ai essayé des choses comme celle-ci:

    for i in $(some command); do
      echo $i | cut -f2 -d"heads/" >> text.txt
    done

Mais je ne sais pas comment le formater dans un tableau sans utiliser de fichier temporaire.
Désolé si la question est stupide et probablement trop facile et je suis sûr que je peux la résoudre moi-même, mais je n'ai tout simplement pas le temps pour elle parce que c'est juste une fonctionnalité supplémentaire que je souhaite personnellement mettre en œuvre.

2
Petar Nikolov 20 nov. 2018 à 18:56

4 réponses

Meilleure réponse

Utilisation de Perl one-liner

$ cat petar.txt
    awd54a7w6ds54awd47awd refs/heads/SomeInfo1
    awdafawe23413f13a3r3r refs/heads/SomeInfo2
    a8wd5a8w5da78d6asawd7 refs/heads/SomeInfo3
    g9reh9wrg69egs7ef987e refs/heads/SomeInfo4

$ perl -ne ' { /.*\/(.*)/ and push(@res,"\"$1\"") } END { print "[".join(",",@res)."]\n" }' petar.txt
["SomeInfo1","SomeInfo2","SomeInfo3","SomeInfo4"]
0
stack0114106 20 nov. 2018 à 20:27

Essaye ça

# json_encoder.sh
arr=()
while read line; do
  arr+=(\"$(basename "$line")\")
done
printf "[%s]" $(IFS=,; echo "${arr[*]}")

Et puis invoquez

./your_command | json_encoder.sh

PS. Personnellement, je fais ce genre de massages de données avec Vim.

2
Elias Toivanen 20 nov. 2018 à 16:22

Bien que vous deviez rarement utiliser un script pour formater json, dans votre cas, vous analysez simplement la sortie dans une ligne séparée par des virgules avec des finitions supplémentaires de [...]. Vous pouvez utiliser extension des paramètres bash pour éviter de générer des sous-shell supplémentaires afin d'obtenir le dernier champ d'informations de chaque ligne comme suit:

#!/bin/bash

[ -z "$1" -o ! -r "$1" ] && {   ## validate file given as argument
    printf "error: file doesn't exist or not readable.\n" >&2
    exit 1
}

c=0     ## simple flag variable

while read -r line; do                  ## read each line
    if [ "$c" -eq '0' ]; then           ## is flag 0?
        printf "[\"%s\"" "${line##*/}"  ## output ["last"
    else                                ## otherwise
        printf ",\"%s\"" "${line##*/}"  ## output ,"last"
    fi
    c=1         ## set flag 1
done < file     ## redirect file to loop
echo "]"        ## append closing ]

Exemple d'utilisation / de sortie

En utilisant vos données comme fichier d'entrée, vous obtiendrez ce qui suit:

$ bash script.sh file
["SomeInfo1","SomeInfo2","SomeInfo3","SomeInfo4"]

Regardez les choses et faites-moi savoir si vous avez des questions.

0
David C. Rankin 20 nov. 2018 à 17:07

Vous pouvez également utiliser awk sans aucune boucle je suppose:

cat prev_output | awk -v ORS=',' -F'/' '{print "\042"$3"\042"}' | \
sed 's/^/[/g ; s/,$/]\n/g' > new_output

cat new_output
["SomeInfo1","SomeInfo2","SomeInfo3","SomeInfo4"]
0
MikeKatz45 20 nov. 2018 à 17:13