[RÉSOLU] Passer une sortie échapée comme paramètre à une commande BASH

XARGS à moi !

a marqué ce sujet comme résolu.

Bonjour à toutes et tous,

j’ai besoin d’effectuer des traitements sur une liste de fichier filtrés à partir d’une commande git.

Rien de compliqué mais voilà: je connais mes utilisateurs et je souhaite prévoir le cas ou le nom de fichier contient des espaces, guillemets.

ex:

$ git diff --name-only --cached -- '*.rs'
fichier1.rs
"nom \"a la noix\" pour 'moi.rs"

Ultra simplifié pour l’exemple voici ce que je cherche à faire:

$ git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs cat # Le grep est juste la pour exemple: commande git -> filtrage -> passage des noms de fichier en param d'une commande.

Et là c’est le drame:

xargs: guillemets simple non appairés ; par défaut les guillemets sont particuliers à xargs à moins d'utiliser l'option -0
cat: 'nom \a': Aucun fichier ou dossier de ce type
cat: la: Aucun fichier ou dossier de ce type
cat: 'noix"': Aucun fichier ou dossier de ce type
cat: pour: Aucun fichier ou dossier de ce type

Quelques recherches, je reviens à la charge:

$ git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs -rd '\n' printf '%s'
fichier1.rs"nom \"a la noix\" pour 'moi.rs"

Cela semble mieux non ? J’essaie ?

$ git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs -rd '\n ' cat
cat: '"nom \"a la noix\" pour '\''moi.rs"': Aucun fichier ou dossier de ce type

Peut être devrais-je le passer tel quel à xargs avec l’option -0 ?

$ git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs -0 cat
cat: '''fichier1.rs'$'\n''"nom \"a la noix\" pour '\''moi.rs"'$'\n': Aucun fichier ou dossier de ce type

Non…

Quelques chose m’échappe savez vous quoi ?

(«m’échappe» vous l’avez ? :B )

+0 -0

git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs -I {} cat {}

C’est mieux comme ça ? xargs est une plaie à utiliser.

Es-tu sûr de faire la commande dans le dossier racine de ton dépôt git ? Car git diff donne des chemins relatif à la racine. Il existe bien une option relative, mais elle n’affiche que les différences internes au dossier courant.

+1 -0

Pour pouvoir utiliser xargs avec -0, qui signifie que les noms de fichiers sont transmis comme des chaînes C, il faut utiliser grep avec --null ou l’équivalent de ton implémentation.
Ceci dit, je ne vois pas l’utilité du -E à grep dans tes exemples, mais c’est une autre histoire.

+0 -0

Autre possibilité à envisager : tu es obligé d’utiliser Bash ? De mon point de vue ça ressemble au genre de tâches qui se fait très bien avec n’importe quel langage de script capable d’accéder à des API Git et de lancer des programmes arbitraires.

Les intérêts dans ton cas, ce serait un script plus lisible, plus maintenable, plus souple dans les possibilités de filtrage, sans être obligé de jongler avec des chaines de caractères pour essayer de retrouver les noms de fichiers concernés.

Évidemment c’est surtout intéressant si tu as besoin d’un script pérenne et pas juste d’un truc lancé une seule fois.

Là ici, s’il utiliserait un script bash ça serait plus simple. Le problème ici c’est que c’est one-liner.

bash n’est pas idéal mais fonctionne bien tout de même.

+0 -0

git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs -I {} cat {}

ache

Malheureusement, cela ne marche pas mieux:

git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs -I {} cat {}
xargs: guillemets simple non appairés ; par défaut les guillemets sont particuliers à xargs à moins d'utiliser l'option -0

Avec l’option -0:

$ git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs -0 -I {} cat "{}"
cat: '''fichier1.rs'$'\n''"nom \"a la noix\" pour '\''moi.rs"'$'\n': Aucun fichier ou dossier de ce type

Es-tu sûr de faire la commande dans le dossier racine de ton dépôt git ? Car git diff donne des chemins relatif à la racine. Il existe bien une option relative, mais elle n’affiche que les différences internes au dossier courant.

ache

Cela ne pose pas de pb: la finalité est l’utilisation dans un hook (j’ajoute pour les curieux que j’ai des contraintes qui m’empêchent d’utiliser une lib genre pre-commit avec laquelle je travaille pourtant d’habitude…)

Pour pouvoir utiliser xargs avec -0, qui signifie que les noms de fichiers sont transmis comme des chaînes C, il faut utiliser grep avec --null ou l’équivalent de ton implémentation.

Gil Cot

À moins que je n’ai mal compris ta solution, le résultat est similaire:

$ git diff --name-only --cached -- '*.rs' | grep --null --color=no -E '.*' | xargs -0 cat 
cat: '''fichier1.rs'$'\n''"nom \"a la noix\" pour '\''moi.rs"'$'\n': Aucun fichier ou dossier de ce type

Ceci dit, je ne vois pas l’utilité du -E à grep dans tes exemples, mais c’est une autre histoire.

Gil Cot

En effet, le grep ici ne sert qu’a montrer un contexte simplifé, je l’ai ajouté pour préciser qu’un ensemble de traitement était réalisé dont un grep :)

De mon point de vue ça ressemble au genre de tâches qui se fait très bien avec n’importe quel langage de script capable d’accéder à des API Git et de lancer des programmes arbitraires. Les intérêts dans ton cas, ce serait un script plus lisible, plus maintenable, plus souple dans les possibilités de filtrage, sans être obligé de jongler avec des chaines de caractères pour essayer de retrouver les noms de fichiers concernés. Évidemment c’est surtout intéressant si tu as besoin d’un script pérenne et pas juste d’un truc lancé une seule fois.

SpaceFox

J’en conviens, et il me semble envisageable d’utiliser Python pour ce script ce que je ferais en l’absence de solution. L’avantage que je vois à BASH c’est que, lançant un grand nombre de commande aux retours parfois mmh… exotique, je m’évite de fastidieux traitement de sortie. Et puis je suis à l’aise avec BASH pour cet usage d’habitude :) .

Cependant ma curiosité restera entière: comment passer à xargs une entrée telle que celle ci ? Cette question risque de hanter mes nuits c’est pourquoi je persiste :D

Là ici, s’il utiliserait un script bash ça serait plus simple. Le problème ici c’est que c’est one-liner. bash n’est pas idéal mais fonctionne bien tout de même.

ache

Je ne suis pas contre cette option cependant en quoi plusieurs lignes permettraient de régler le problème ?

+0 -0

Je ne suis pas contre cette option cependant en quoi plusieurs lignes permettraient de régler le problème ?

Déjà, tu ne t’embêtes plus avec xargs et sa gestion particulière des chaînes.

Ensuite, ça permet de bien structurer ce que tu fais, des structures de contrôles et l’utilisation de variable pour nommer les étapes intermédiaires. Ici, on pourrait séparer l’étape où on liste les fichiers de celle où on filtre les fichiers. Je ne l’ai pas fait mais ça ressemblerais à ça.

#!/bin/bash

FILE_TO_BATCH=$(git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*')
BATCH_COMMAND=cat

for file in $FILE_TO_BATCH
do
  $BATCH_COMMAND $file
done

Bref, le problème à l’ai plus complexe que juste ça. Est-ce que tu pourrais nous transmettre tes versions de xargs, grep et git ? Histoire que l’on comprennent pourquoi une commande qui marche chez nous ne marche pas chez toi.

+1 -0

Je ne suis pas contre cette option cependant en quoi plusieurs lignes permettraient de régler le problème ? Ensuite, ça permet de bien structurer ce que tu fais, des structures de contrôles et l’utilisation de variable pour nommer les étapes intermédiaires. Ici, on pourrait séparer l’étape où on liste les fichiers de celle où on filtre les fichiers. Je ne l’ai pas fait mais ça ressemblerais à ça.

Déjà, tu ne t’embêtes plus avec xargs et sa gestion particulière des chaînes.

ache

En effet :)

Bref, le problème à l’ai plus complexe que juste ça. Est-ce que tu pourrais nous transmettre tes versions de xargs, grep et git ? Histoire que l’on comprennent pourquoi une commande qui marche chez nous ne marche pas chez toi.

ache

Voici les versions de mes outils:

$ xargs --version
xargs (GNU findutils) 4.7.0

$ grep --version
grep (GNU grep) 3.4

$ git --version
git version 2.25.1

Je suis d’accord avec toi, cela semble un peu plus complexe que je ne l’imaginais.

FILE_TO_BATCH=$(git diff --name-only --cached -- '*.rs' | grep --null --color=no -E '.*')
echo $FILE_TO_BATCH
BATCH_COMMAND=cat

for file in $FILE_TO_BATCH
do
    echo "On cat $file"
  $BATCH_COMMAND "$file"
done

En sortie: 

fichier1.rs "nom \"a la noix\" pour 'moi.rs"

On cat fichier1.rs
Fichier 1 est impriméFichier 1 est imprimé
On cat "nom
cat: '"nom': Aucun fichier ou dossier de ce type
On cat \"a
cat: '\"a': Aucun fichier ou dossier de ce type
On cat la
cat: la: Aucun fichier ou dossier de ce type
On cat noix\"
cat: 'noix\"': Aucun fichier ou dossier de ce type
On cat pour
cat: pour: Aucun fichier ou dossier de ce type
On cat 'moi.rs"
cat: ''\''moi.rs"': Aucun fichier ou dossier de ce type

Une manière simple de reproduire sans installer git peut être d’utiliser ls -1

$ ls --version
ls (GNU coreutils) 8.30
# Conditions initiales
touch 'nom "a la noix" pour '\''moi.rs'
echo "Victoire de \"cat\" pour nom à la noix !" >> 'nom "a la noix" pour '\''moi.rs'

touch fichier1.rs
echo "Fichier 1 est imprimé" >> fichier1.rs
FILE_TO_BATCH="$(ls -1 *.rs | grep --null --color=no -E '.*')"

echo "$FILE_TO_BATCH"

for file in ${FILE_TO_BATCH}
do
  echo "On cat $file"
  cat "$file"
done

Donne en sortie:

fichier1.rs nom "a la noix" pour 'moi.rs

On cat fichier1.rs
Fichier 1 est impriméFichier 1 est imprimé
On cat nom
cat: nom: Aucun fichier ou dossier de ce type
On cat "a
cat: '"a': Aucun fichier ou dossier de ce type
On cat la
cat: la: Aucun fichier ou dossier de ce type
On cat noix"
cat: 'noix"': Aucun fichier ou dossier de ce type
On cat pour
cat: pour: Aucun fichier ou dossier de ce type
On cat 'moi.rs
cat: "'moi.rs": Aucun fichier ou dossier de ce type

J’en profite pour vois remmercier de vos réponses et pour votre temps <3

Pour pouvoir utiliser xargs avec -0, qui signifie que les noms de fichiers sont transmis comme des chaînes C, il faut utiliser grep avec --null ou l’équivalent de ton implémentation.

auto-citation

En relisant attentivement, je vois que tu indiques

$ git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs -rd '\n' printf '%s'
fichier1.rs"nom \"a la noix\" pour 'moi.rs"

Cela semble mieux non ? J’essaie ?

$ git diff --name-only --cached -- '*.rs' | grep --color=no -E '.*' | xargs -rd '\n ' cat
cat: '"nom \"a la noix\" pour '\''moi.rs"': Aucun fichier ou dossier de ce type

Cela me fait tiquer et en remontant je vois c’est le bon nom qui est transmis au chat…

$ git diff --name-only --cached -- '*.rs'
fichier1.rs
"nom \"a la noix\" pour 'moi.rs"

En fait git-diff fait le « quoting » des noms contenant des caractères problématiques (espaces, simples ou doubles quotes, etc.) Ceci explique ton constat :

À moins que je n’ai mal compris ta solution, le résultat est similaire:

Nogs

La même remarque que pour le « grepage » s’applique donc ici et chez moi je vois que c’est l’option -z

git diff -z --name-only --cached -- '*.rs' | xargs -0 ls
# si le résultat est satisfaisant, remplacer ls par cat

édition : Mais cela ne répond qu’en partie je pense, vu que tu as d’autres traitements au milieu (qui doivent comprendre que leurs entrées sont « null-delimited » et produire une sortie pareille jusqu’au bout.

+1 -0

Je ne suis pas contre cette option cependant en quoi plusieurs lignes permettraient de régler le problème ? Ensuite, ça permet de bien structurer ce que tu fais, des structures de contrôles et l’utilisation de variable pour nommer les étapes intermédiaires. Ici, on pourrait séparer l’étape où on liste les fichiers de celle où on filtre les fichiers. Je ne l’ai pas fait mais ça ressemblerais à ça.

Déjà, tu ne t’embêtes plus avec xargs et sa gestion particulière des chaînes.

ache

Attention que les chaînes restent particulières et qu’il faut prendre des précautions.
Ce n’est pas xargs en lui-même qui a une gestion particulière des chaînes, c’est plutôt qu’il a un mécanisme pour se prémunir des particularités/limites du shell…

[…]

Une manière simple de reproduire sans installer git peut être d’utiliser ls -1

$ ls --version
ls (GNU coreutils) 8.30
# Conditions initiales
touch 'nom "a la noix" pour '\''moi.rs'
echo "Victoire de \"cat\" pour nom à la noix !" >> 'nom "a la noix" pour '\''moi.rs'

touch fichier1.rs
echo "Fichier 1 est imprimé" >> fichier1.rs
FILE_TO_BATCH="$(ls -1 *.rs | grep --null --color=no -E '.*')"

echo "$FILE_TO_BATCH"

for file in ${FILE_TO_BATCH}
do
  echo "On cat $file"
  cat "$file"
done

Donne en sortie:

fichier1.rs nom "a la noix" pour 'moi.rs

On cat fichier1.rs
Fichier 1 est impriméFichier 1 est imprimé
On cat nom
cat: nom: Aucun fichier ou dossier de ce type
On cat "a
cat: '"a': Aucun fichier ou dossier de ce type
On cat la
cat: la: Aucun fichier ou dossier de ce type
On cat noix"
cat: 'noix"': Aucun fichier ou dossier de ce type
On cat pour
cat: pour: Aucun fichier ou dossier de ce type
On cat 'moi.rs
cat: "'moi.rs": Aucun fichier ou dossier de ce type

Nogs

Je fais l’exercice ^^

0 $ mkdir tst
0 $ cd tst
0 $ touch 'nom "a la noix" pour '\''moi.rs'
0 $ echo "Victoire de \"cat\" pour nom à la noix !" >> 'nom "a la noix" pour '\''moi.rs'
> ^C
1 $ echo "Victoire de \"cat\" pour nom à la noix \!" >> 'nom "a la noix" pour '\''moi.rs'
0 $ # 'nom^I pour autocompleter
0 $ touch fichier1.rs
0 $ echo "Fichier 1 est imprimé" >> fichier1.rs
0 $ ls -1
fichier1.rs
nom "a la noix" pour 'moi.rs

Avant de poursuivre, tu remarques que tu ne passes pas ton nom de fichier dans la boucle mais les morceaux découpés par le shell (c’est aussi confus pour la boucle for ici que pour xargs héhé (raison pour laquelle je dis qu’il ne faut pas accuser ce dernier trop tôt.)

0 $ for f in $(ls -1 *.rs); do echo "$f"; done
fichier1.rs
nom
"a
la
noix"
pour
'moi.rs
0 $ for f in "$(ls -1 *.rs)"; do echo "$f"; done 
fichier1.rs
nom "a la noix" pour 'moi.rs

Est-ce gagné ? Non… On a juste réussi à faire un écho simple. :D

0 $ for f in "$(ls -1 *.rs)"; do echo "==on cat $f=="; done
==on cat fichier1.rs
nom "a la noix" pour 'moi.rs==
0 $ for f in $(ls -1 *.rs); do echo "==on cat $f=="; done
==on cat fichier1.rs==
==on cat nom==
==on cat "a==
==on cat la==
==on cat noix"==
==on cat pour==
==on cat 'moi.rs==
0 $ for f in "$(ls -1 *.rs)"; do cat "$f"; done
cat: fichier1.rs
nom "a la noix" pour 'moi.rs: No such file or directory
1 $ for f in $(ls -1 *.rs); do cat "$f"; done
Fichier 1 est imprimé
cat: nom: No such file or directory
cat: "a: No such file or directory
cat: la: No such file or directory
cat: noix": No such file or directory
cat: pour: No such file or directory
cat: 'moi.rs: No such file or directory

C’est le cas dans lequel tu étais. Et c’est typiquement le genre d’exemple qui montre que ls est bien pour un usage interactif mais pas en script… (ou en utilisant quelque option obscure et non portable…) La même boucle tournée autrement

1 $ find . -name '*.rs' -exec echo "{}" \;
./nom "a la noix" pour 'moi.rs
./fichier1.rs
0 $ find . -name '*.rs' -exec echo "==on cat {}==" \;
==on cat ./nom "a la noix" pour 'moi.rs==
==on cat ./fichier1.rs==
0 $ find . -name '*.rs' -print
./nom "a la noix" pour 'moi.rs
./fichier1.rs
0 $ # -print est le comportement par defaut
0 $ # -print est comme -exec echo {} \;
# -exec est un xargs -n 1 simple...
0 $ find . -name '*.rs' | xargs -n 1 echo
./nom
a la noix
pour
xargs: unterminated quote
1 $ # c'est le traitement du shell : separation aux blancs...
1 $ find . -name '*.rs' -print0 | xargs -0 -n 1 echo
./nom "a la noix" pour 'moi.rs
./fichier1.rs
0 $ # on dit de ne pas considerer les blancs mais...
# ...que les chaines finissent par \0 plutot
0 $ find . -name '*.rs' -print0 | xargs -0 -I FILE -n 1 echo "==on cat FILE=="
==on cat ./nom "a la noix" pour 'moi.rs==
==on cat ./fichier1.rs==
0 $ find . -name '*.rs' -print0 | xargs -0 -n 1 cat
Victoire de "cat" pour nom à la noix \!
Fichier 1 est imprimé

Je suis sous FreeBSD là et mon xargs n’est pas l’implémentation GNU, donc pas d’option -d. Mais ceci devrait marcher aussi : find . -name '*.rs' | xargs -d '\n' -n 1 echo

Du coup, j’ai plutôt choisi de transmettre les noms encodés comme pour un programme C (et je pense que c’est ce que voient les API) d’un côté, et j’en informe xargs de l’autre côté (jusque là, ce n’est pas lui qui a un traitement particulier des chaînes de caractères.) Même chose, comme je mentionnais déjà, pour git diff à qui il faut dire (via -z) de transmettre le nom tel quel (sinon il rajoute en plus des "quotes" et c’est plus le même nom qui est vu ensuite) et en format natif (i.e. pour API)

Jusque là, tu noteras que je n’ai pas encore évoqué le cas de grep …parce-que sa fonction est d’extraire les lignes qui matchent… Donc dans l’enchaînement, ce n’est plus le fichier qui est vu par ton xargs mais les lignes issues de grep :-° Passer en script permet d’y voir probablement plus clair. En attendant, je reviens à la boucle sans ls cette fois

0 $ for f in $(find . -name '*.rs'); do echo "$f"; done
./nom
"a
la
noix"
pour
'moi.rs
./fichier1.rs
0 $ for f in "$(find . -name '*.rs')"; do echo "$f"; done
./nom "a la noix" pour 'moi.rs
./fichier1.rs
0 $ # sournoiserie de shell ?
0 $ for f in "$(find . -name '*.rs')"; do echo "==on cat $f=="; done
==on cat ./nom "a la noix" pour 'moi.rs
./fichier1.rs==
0 $ for f in "$(find . -name '*.rs' -print0)"; do echo "==on cat $f=="; done
==on cat ./nom "a la noix" pour 'moi.rs./fichier1.rs==
0 $ for f in $(find . -name '*.rs' -print0); do echo "==on cat $f=="; done
==on cat ./nom==
==on cat "a==
==on cat la==
==on cat noix"==
==on cat pour==
==on cat 'moi.rs./fichier1.rs==
0 $ # on est limite par le traitement du shell...
0 $ # et on voit la chaine avec les \0 et non des \n
0 $ for f in "$(find . -name '*.rs')"; do cat "$f"; done
cat: ./nom "a la noix" pour 'moi.rs
./fichier1.rs: No such file or directory
1 $ # en mode script ce ne serait pas la voix...

Alors, qu’est-ce que conseille si on doit faire un script dans ce cas ? :diable: On y était presque…

find . -name '*.rs' -print0 | 
    while IFS= read -r -d '' line; do 
        echo "==on cat $line=="
        cat "$line"
    done

Le truc est d’utiliser while au lieu de for en ayant soin de d’adapter les délimiteurs partout. :B
(testé et approuvé chez moi, avec bash comme shell)

1 $ find . -name '*.rs' -print0 | while IFS= read -r -d '' line; do echo "==on cat $line=="; done
==on cat ./nom "a la noix" pour 'moi.rs==
==on cat ./fichier1.rs==
0 $ find . -name '*.rs' -print0 | while IFS= read -r -d '' line; do echo "==on cat $line=="; cat "$line"; done
==on cat ./nom "a la noix" pour 'moi.rs==
Victoire de "cat" pour nom à la noix \!
==on cat ./fichier1.rs==
Fichier 1 est imprimé

On peut en général garder aussi, dans ces cas-ci, la séparation par saut de ligne habituelle…

find . -name '*.rs' -print | 
    while IFS=$'\n' read -r -d $'\n' line; do 
        echo "==on cat $line=="
        cat "$line"
    done

(et du coup, on peut utiliser ls aussi jusqu’au prochain souci…)

0 $ ls -1 *.rs | while IFS=$'\n' read -r -d $'\n' line; do echo "==on cat $line=="; cat "$line"; done
==on cat fichier1.rs==
Fichier 1 est imprimé
==on cat nom "a la noix" pour 'moi.rs==
Victoire de "cat" pour nom à la noix \!

et voilà :soleil: and sorry for the length

+2 -0

Merci Gil Cot pour ces réponses qui me font reconsidérer l’usage d’un while avec read dans ces cas mais aussi l’existence du séparateur NUL qui m’était totalement passé sous les radars.

Je constate qu’il est aussi possible de faire:

git diff --name-only -z --cached -- '*.rs' | 
    while IFS=$'\0' read -r -d $'\0' line; do 
    echo $line
done

afin de traiter les fichiers un à un en évitant les problèmes de quoting de git-diff.

Du coup, je propose la résolution du tout premier problème que je décrivais avec des pipes:

# git diff -z : utilise le caractère NULL dans la sortie et revoie les chaînes brutes (sans quotes comme dit dans le réponse de Gil Cot)
# grep --null-data : permet d'accepter les chaînes brutes en entrée de grep
git diff --name-only --cached -z -- '*.rs' | grep --null-data --color=no -E '.*'  | xargs -0 cat 

Attention que ton grep envoie les lignes qui matchent (ou ces lignes préfixé du nom du fichiers) alors que tu xargs est supposé donner des noms de fichiers à cat

$ grep '.*' fichier1.rs 
Fichier 1 est imprimé
$ # toute la ligne en couleur

Je te suggère de remplacer --color=no par --files-with-matches et éventuellement de rajouter (une fois que tu as fini de tester) --no-messages

+0 -0

Attention que ton grep envoie les lignes qui matchent (ou ces lignes préfixé du nom du fichiers) alors que tu xargs est supposé donner des noms de fichiers à cat

Gil Cot

J’ai l’impression qu’il y a confusion, ici l’input (la sortie de git diff) est déjà une liste de noms de fichiers, qui est juste filtrée par grep avant d’être filée comme arguments à cat. L’option --files-with-matches est utile avec rgrep, mais pas ici (ça va juste répondre «(standard input)»).

Ou j’ai rien compris ?

Je pensais qu’il s’agissait de rechercher un motif dans les fichiers modifiés, et m’étais demandé initialement pourquoi n’avoir pas passé le grep à xargs …ou sinon, t’as raison lxnv, il aurait fallu effectivement écrire grep --null --color=no -l -s '.*' $(git diff --name-only --cached -z -- '*.rs') | xargs -0 cat

Je n’avais pas du tout pensé qu’il s’agissait de refiltrer les noms des fichiers (parce-que ayant vu la restriction *.rs avant et le motif '.*' ensuite.) En plus j’avais oublié que le pipe impliquait qu’on avait le contenu dans lequel chercher (soit stdin, et donc plus de fichier à lui passer) Du coup, c’est plutôt git diff --name-only --cached -z -- '*.rs' | grep -z --line-buffered -s '.*' | xargs -0 cat que j’aurais du recommander.

Désolé pour la confusion du coup.

+1 -0
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte