« Bash command line » : différence entre les versions
(→pigz) |
|||
(64 versions intermédiaires par le même utilisateur non affichées) | |||
Ligne 28 : | Ligne 28 : | ||
<kode lang='bash'> | <kode lang='bash'> | ||
# chercher une occurrence dans les fichiers d'un dossier | # chercher une occurrence dans les fichiers d'un dossier | ||
rg | rg [occurence] [path] | ||
# -C5 affiche 5 lignes avant et après les correspondances | # -C5 affiche 5 lignes avant et après les correspondances | ||
# -uu rechercher dans les fichiers et dossiers cachés (.*) | # -uu rechercher dans les fichiers et dossiers cachés (.*) | ||
# -g | # -i/--ignore-case | ||
# -g '*.txt' rechercher dans les fichiers correspondant au pattern | |||
# -g '!*.txt' rechercher dans les fichiers ne correspondant pas au pattern | |||
# -c count the matched lines per matching file | |||
# search in pdf | |||
rg --pre ripgrep-preprocess-pdf.sh --pre-glob '*.pdf' [occurence] | |||
</kode> | </kode> | ||
<filebox fn='ripgrep-preprocess-pdf.sh' collapsed> | |||
#!/bin/bash | |||
set -e | |||
set -o pipefail | |||
set -u | |||
if [ -s "$1" ]; then | |||
exec pdftotext - - | |||
else | |||
exec cat | |||
fi | |||
</filebox> | |||
== grep == | == grep == | ||
Ligne 142 : | Ligne 162 : | ||
== sed (Stream EDitor) == | == sed (Stream EDitor) == | ||
=== regex === | === regex === | ||
{| class="wikitable wtp" | {| class="wikitable wtp wtmono1" | ||
|- | |- | ||
| [0-9] || chiffre, \d n'existe pas | | [0-9] <nowiki>[[:digit:]]</nowiki> || chiffre, {{boxx|\d}} n'existe pas | ||
|- | |- | ||
| \s || espace, tab | | \s || espace, tab | ||
|- | |||
| \w || character {{boxx|[0-9a-zA-Z_]}} | |||
|} | |} | ||
* Mode basic regex, échapper {{boxx|? + { } ( )}} | * Mode basic regex, échapper {{boxx|? + { } }}, {{boxx|\( \)}} sont utilisés pour les groupes | ||
* Mode extended regex {{boxx|-r}}, | * Mode extended regex {{boxx|-r}}, échapper {{boxx|( )}} car utilisés pour les groupes | ||
=== Remplacer du texte === | === Remplacer du texte === | ||
Ligne 155 : | Ligne 177 : | ||
<kode lang="bash"> | <kode lang="bash"> | ||
# remplacer des occurrences dans un fichier texte | # remplacer des occurrences dans un fichier texte | ||
sed | sed "s/occurrence à remplacer/texte de substitution/drapeaux" -i fichier-cible.txt | ||
# dry run: afficher la sortie au lieu de remplacer dans le fichier | # dry run: afficher la sortie au lieu de remplacer dans le fichier | ||
Ligne 161 : | Ligne 183 : | ||
# utilisation des groupes | # utilisation des groupes | ||
sed | sed "s/\(groupe 1\) \(groupe 2\)/\1 \2/" -i fichier-cible.txt | ||
# caractères spéciaux | # caractères spéciaux | ||
sed | sed "s/[0-9]\+\.[0-9]\{1,2\}/ /" -i fichier-cible.txt | ||
# utiliser les simples quotes et un autre signe de séparation : # | # utiliser les simples quotes et un autre signe de séparation : # | ||
sed | sed 's#occurrence à remplacer#texte de substitution#drapeaux' -i fichier-cible.txt | ||
# échapper des simples quotes | # échapper des simples quotes | ||
Ligne 179 : | Ligne 201 : | ||
echo '123\\456' | sed 's/\\/+/' | echo '123\\456' | sed 's/\\/+/' | ||
echo '123\\456' | sed "s/\\\\/+/" | echo '123\\456' | sed "s/\\\\/+/" | ||
# multiple replace | |||
sed 's/regex1/txt1/; s/regex2/txt2/;' fichier.txt | |||
sed ' | |||
s/regex1/txt1/ | |||
s/regex2/txt2/' \ | |||
-i fichier.txt | |||
</kode> | </kode> | ||
Ligne 197 : | Ligne 226 : | ||
sed -n -r 's/regex (groupe) regex/\1/p' fichier.txt | sed -n -r 's/regex (groupe) regex/\1/p' fichier.txt | ||
# -n: suppress automatic printing of pattern space | # -n: suppress automatic printing of pattern space | ||
# -r: use extended regular expressions such as \1 | |||
# use grep | |||
grep -Eo 'regex' | |||
# -E: interpret PATTERN as an extended regular expression | |||
# -o: print only the matched (non-empty) parts of a matching line | |||
</kode> | </kode> | ||
Ligne 404 : | Ligne 439 : | ||
# lister les fichiers par date, le plus récent en premier | # lister les fichiers par date, le plus récent en premier | ||
ls -thor | ls -thor | ||
</kode> | |||
== [https://the.exa.website/ exa] == | |||
Modern replacement for ls. | |||
<kode lang='bash'> | |||
# -1: display one entry per line | |||
exa -1 --icons | |||
# -l: display extended file metadata as a table | |||
# -g: list each file’s group | |||
exa -lg --icons | |||
# -a: show hidden and “dot” files. Use this twice to also show the `.' and `..' directories | |||
exa -lgaa --icons | |||
</kode> | </kode> | ||
Ligne 426 : | Ligne 475 : | ||
# si folder2 existe déjà et que l'on veut copier le contenu de folder1 dans folder2 | # si folder2 existe déjà et que l'on veut copier le contenu de folder1 dans folder2 | ||
cp -r /folder1/. /folder2 | cp -r /folder1/. /folder2 | ||
# -f to overwrite without asking | |||
</kode> | |||
== rm == | |||
<kode lang='bash'> | |||
# remove all files except file1.txt and file2.txt | |||
shopt -s extglob | |||
rm -i !(file1|file2).txt | |||
shopt -u extglob | |||
# zsh | |||
setopt extended_glob | |||
rm -i -- ^(file1|file2).txt | |||
</kode> | |||
== [https://github.com/andreafrancia/trash-cli trash-cli] == | |||
<kode lang='bash'> | |||
# move a file to the trash | |||
trash-put [filename] | |||
# display the content of the trash and allow to select which files to restore | |||
trash-restore | |||
# empty the trash | |||
trash-empty | |||
# list the content of the trash | |||
trash-list | |||
</kode> | </kode> | ||
Ligne 435 : | Ligne 513 : | ||
fd -e png | fd -e png | ||
# regex | # regex | ||
fd '^ | fd '^\w{2,3}\.json$' | ||
# type: Fichier, Dossier, symLink, eXecutable, Empty | # type: Fichier, Dossier, symLink, eXecutable, Empty | ||
fd -t f | fd -t f | ||
Ligne 443 : | Ligne 521 : | ||
fd -I xxx | fd -I xxx | ||
# exclure | # exclure | ||
fd -E /mnt/external-drive ' | fd '*.bak' -E /mnt/external-drive | ||
# execute command -x: for each match, -X: for all matches as parameters | |||
fd -t f '^\w{2,3}(-\w+)?\.json$' -E fr.json -E en.json -X rm -f | |||
</kode> | </kode> | ||
Ligne 486 : | Ligne 566 : | ||
</kode> | </kode> | ||
== du | == Disc usage == | ||
=== df === | |||
Displays the amount of space available on the file systems | |||
<kode lang='bash'> | |||
df -hl -x tmpfs -x devtmpfs -x overlay | |||
# -h print sizes in powers of 1024 (e.g., 1023M) | |||
# -l limit listing to local file systems | |||
# -x limit listing to file systems not of type TYPE | |||
</kode> | |||
=== du === | |||
* -s, --summarize : display only a total for each argument | * -s, --summarize : display only a total for each argument | ||
* -h, --human-readable: print sizes in human readable format (e.g., 1K 234M 2G) | * -h, --human-readable: print sizes in human readable format (e.g., 1K 234M 2G) | ||
Ligne 492 : | Ligne 582 : | ||
# taille du dossier | # taille du dossier | ||
du -hs dossier | du -hs dossier | ||
</kode> | |||
=== [https://github.com/bootandy/dust dust] === | |||
<kode lang='bash'> | |||
# display the size of the bigest folders and their bigest content (21 directories/lines by default) | |||
dust -br /path | |||
# -b do not show percentages or draw ASCII bars | |||
# -r reverse order of output, with root at the lowest | |||
# display the size of all the folders | |||
dust -brd 1 /path | |||
# -d 1 shows 1 level of subdirectories + remove restriction on the number of directories/lines displayed | |||
# display the size of the bigest folders and their bigest content (10 directories/lines) | |||
dust -brn 10 /path | |||
# -n 10 shows 10 directories/lines instead of the 21 default | |||
# install | |||
cargo install du-dust | |||
</kode> | </kode> | ||
== chmod == | == chmod == | ||
<kode lang=bash> | <kode lang=bash> | ||
# chmod [ | # chmod [ugo][+-][rwxXst] fichier-ou-dossier | ||
# X get execute rights only to directories and to files which already have execute permission for some user | |||
# forcer les droits u:rw g:r o:r | # forcer les droits u:rw g:r o:r | ||
Ligne 506 : | Ligne 616 : | ||
# supprimer tous les droits write à tous les éléments d'un répertoire | # supprimer tous les droits write à tous les éléments d'un répertoire | ||
# (non récursif et ne s'applique pas au répertoire) | # (non récursif et ne s'applique pas au répertoire) | ||
chmod | chmod -w dossier/* | ||
# supprimer tous les droits write à tous les éléments d'un répertoire | # supprimer tous les droits write à tous les éléments d'un répertoire | ||
# (récursif et s'applique aussi au répertoire) | # (récursif et s'applique aussi au répertoire) | ||
chmod -R | chmod -R -w dossier | ||
# donne au groupe les mêmes droits que ceux de l'utilisateur | # donne au groupe les mêmes droits que ceux de l'utilisateur | ||
Ligne 572 : | Ligne 682 : | ||
setfacl -b /path/folder | setfacl -b /path/folder | ||
</kode> | </kode> | ||
== Connaitre le type MIME d'un fichier == | |||
<kode lang=bash> | |||
xdg-mime query filetype fichier.ext | |||
# image/jpeg | |||
file -b -i fichier.ext | |||
# image/jpeg; charset=binary | |||
</kode> | |||
== [https://github.com/sharkdp/bat bat] == | |||
A cat clone with syntax highlighting and Git integration. | |||
<kode lang='bash'> | |||
bat /path/file.ext | |||
</kode> | |||
<filebox fn='.zshenv' lang=bash> | |||
# use bat as a colorizing pager for man | |||
export MANPAGER="sh -c 'col -bx | bat -l man -p'" | |||
</filebox> | |||
= Archivage = | = Archivage = | ||
Ligne 615 : | Ligne 745 : | ||
* z : gzip | * z : gzip | ||
* j : bzip (bz2) | * j : bzip (bz2) | ||
* --exclude-vcs : exclude Version Control System like {{boxx|.git}} | |||
{{info | {{boxx|tar}} peut deviner le décompresseur à utiliser (gzip, bzip, etc). Il n'est donc pas nécessaire de spécifier les options correspondantes (z, j)}} | {{info | {{boxx|tar}} peut deviner le décompresseur à utiliser (gzip, bzip, etc). Il n'est donc pas nécessaire de spécifier les options correspondantes (z, j)}} | ||
{{info | {{boxx|gzip}} est plus rapide que {{boxx|bzip2}} mais compresse moins.}} | {{info | {{boxx|gzip}} est plus rapide que {{boxx|bzip2}} mais compresse moins.}} | ||
Ligne 645 : | Ligne 776 : | ||
== 7zip == | == 7zip == | ||
<kode lang=bash> | <kode lang=bash> | ||
# | # create an archive with folder1 and file1.ext | ||
7z a -tzip | 7z a archive.7z folder1 file1.ext | ||
# -p to ask for a password | |||
# -tzip to create a zip instead of of 7z | |||
# désarchiver (-o: change the output folder) | # désarchiver (-o: change the output folder) | ||
Ligne 690 : | Ligne 823 : | ||
</kode> | </kode> | ||
= | = Network = | ||
== wget == | == wget == | ||
<kode lang=bash> | <kode lang=bash> | ||
# Télécharger un fichier | # Télécharger un fichier | ||
wget http://...MonFichier.ext | wget http://...MonFichier.ext | ||
# Télécharger un fichier et choisir le dossier de destination | |||
wget http://...MonFichier.ext -P /path | |||
# Renommez le fichier téléchargé | # Renommez le fichier téléchargé | ||
Ligne 725 : | Ligne 851 : | ||
{| class="wikitable wtp" | {| class="wikitable wtp" | ||
|- | |||
| -P || Set directory prefix to prefix, default is . (the current directory). | |||
|- | |- | ||
| --max-redirect=0 || empèche les redirection <tt>302 Moved Temporarily</tt> | | --max-redirect=0 || empèche les redirection <tt>302 Moved Temporarily</tt> | ||
Ligne 768 : | Ligne 896 : | ||
Firefox → Ctrl+Shift+q (Network in Developer Tools) → Reload<br /> | Firefox → Ctrl+Shift+q (Network in Developer Tools) → Reload<br /> | ||
Clique-droit sur une ligne → copy as cURL}} | Clique-droit sur une ligne → copy as cURL}} | ||
= Autres = | |||
== date == | |||
<kode lang=bash> | |||
date +%Y-%m-%d | |||
# 2020-01-30 | |||
date -d "yesterday" +%Y-%m-%d | |||
# 2020-01-29 | |||
</kode> | |||
== secret-tool == | == secret-tool == | ||
Ligne 781 : | Ligne 919 : | ||
{{info | Si plusieurs entrées correspondent aux clé→valeur, la première est retournée.}} | {{info | Si plusieurs entrées correspondent aux clé→valeur, la première est retournée.}} | ||
== [http://www.semicomplete.com/projects/xdotool | == [http://www.semicomplete.com/projects/xdotool xdotool] == | ||
<kode lang='bash'> | <kode lang='bash'> | ||
# Control+v puis Entrée | # Control+v puis Entrée | ||
Ligne 796 : | Ligne 934 : | ||
# bouton 1 de la sourie | # bouton 1 de la sourie | ||
xdotool click 1 | xdotool click 1 | ||
# target a specific window | |||
xdotool search --class 'My window class' windowactivate --sync key Right | |||
# windowactivate --sync active the window and wait until it is activated | |||
# --onlyvisible search only among displayable windows. Useful when the search retrieves multiple results with undisplayable windows. | |||
</kode> | </kode> | ||
{{info | Use {{boxx|xprop}} to get info on a window (name, class)}} | |||
== [http://askubuntu.com/questions/8653/how-to-keep-processes-running-after-ending-ssh-session Détacher un processus] == | == [http://askubuntu.com/questions/8653/how-to-keep-processes-running-after-ending-ssh-session Détacher un processus] == | ||
Ligne 839 : | Ligne 975 : | ||
<kode lang=bash> | <kode lang=bash> | ||
rsvg-convert -w $size -h $size fichier.svg > fichier.png | rsvg-convert -w $size -h $size fichier.svg > fichier.png | ||
</kode> | </kode> | ||
Ligne 898 : | Ligne 1 021 : | ||
{{info | Pour faciliter la coloration, des scripts encapsulent les commandes à colorer.<br> | {{info | Pour faciliter la coloration, des scripts encapsulent les commandes à colorer.<br> | ||
Ces scripts sont placés dans {{boxx|/usr/lib/hl_bin}} et PATH est modifié pour que les nouveaux scripts aient la préséance sur les commandes.}} | Ces scripts sont placés dans {{boxx|/usr/lib/hl_bin}} et PATH est modifié pour que les nouveaux scripts aient la préséance sur les commandes.}} | ||
== [https://linuxcommand.org/lc3_adv_tput.php tput: add color in terminal] == | |||
<kode lang='bash'> | |||
echo -e "$(tput bold; tput setaf 3;)\n= Title =\n$(tput sgr0)" | |||
</kode> | |||
{| class="wikitable wtp" | |||
! Capname | |||
! Description | |||
|- | |||
| bold || start bold text | |||
|- | |||
| smul || start underlined text | |||
|- | |||
| rmul || end underlined text | |||
|- | |||
| setaf || set foreground color | |||
|- | |||
| setab || set background color | |||
|- | |||
| sgr0 || turn off all attributes | |||
|} | |||
{| class="wikitable wtp" | |||
! Color | |||
! Code | |||
|- | |||
| black || 0 | |||
|- | |||
| red || 1 | |||
|- | |||
| green || 2 | |||
|- | |||
| yellow || 3 | |||
|- | |||
| blue || 4 | |||
|- | |||
| magenta || 5 | |||
|- | |||
| cyan || 6 | |||
|- | |||
| white || 7 | |||
|- | |||
| default || 9 | |||
|} | |||
== sleep, timeout == | == sleep, timeout == | ||
Ligne 907 : | Ligne 1 075 : | ||
timeout 1 sleep 2 && echo ok || echo ko | timeout 1 sleep 2 && echo ok || echo ko | ||
# code de retour: 124 (timeout), 0 (ok) | # code de retour: 124 (timeout), 0 (ok) | ||
</kode> | |||
== [https://www.gnu.org/software/bash/manual/html_node/GNU-Parallel.html Parallel] == | |||
Allow to run commands in parallel. The GNU Parallel tool needs to be installed. | |||
<kode lang='bash'> | |||
# list all mp4, then remove extension, then add avi extension | |||
ls *.mp4 | sed -n 's/\.mp4$//p' | parallel echo "{}.avi" | |||
</kode> | |||
== [https://tldr.sh/ tldr] == | |||
Simplified and community-driven man pages with practical examples. | |||
<kode lang='bash'> | |||
tldr [command] | |||
</kode> | |||
== [http://xmlstar.sourceforge.net/doc/UG/xmlstarlet-ug.html#idm47077139670224 XML with xmlstarlet] == | |||
<kode lang='bash'> | |||
# replace: edit update | |||
xml ed -u "/query" --value "new value" file.xml | |||
</kode> | |||
{| class="wikitable wtp" | |||
! Global option | |||
! Description | |||
|- | |||
| L || edit file inplace | |||
|- | |||
| S || preserve non-significant spaces | |||
|- | |||
| O || omit XML declaration (<?xml ...?>) | |||
|} | |||
* [http://xmlstar.sourceforge.net/doc/UG/xmlstarlet-ug.html#idm47077139594320 Editing XML documents] | |||
= script / scriptreplay = | |||
<kode lang='bash'> | |||
# record the command output | |||
script -q -c '[command]' [output-file] | |||
# -q, --quiet: do not write start and done messages to standard output | |||
# display the command output | |||
cat [output-file] | |||
# record the script interaction | |||
script -T [time-file] [output-file] | |||
# -T, --log-timing [time-file]: log timing information to the file | |||
# replay the script interaction | |||
scriptreplay -t [time-file] [output-file] | |||
# -t, --timing [time-file]: file containing script's timing output | |||
</kode> | </kode> |
Dernière version du 6 janvier 2024 à 12:23
Manipulation de string
echo
echo -n "sans retour à la ligne" echo -e "interprétation du caractère d'échappement \r \n" echo # retour à la ligne # affichage avec écrasement de tous les chiffres entre 0 et 100 # et garde affiché les multiples de 10 for i in {1..100..1} do echo -ne "$i\r" sleep .2 if (( $i % 10 == 0 )) ; then echo fi done |
printf
# afficher var sous la forme d'un entier de 2 digits echo $(printf "%02d" $var) |
ripgrep
# chercher une occurrence dans les fichiers d'un dossier rg [occurence] [path] # -C5 affiche 5 lignes avant et après les correspondances # -uu rechercher dans les fichiers et dossiers cachés (.*) # -i/--ignore-case # -g '*.txt' rechercher dans les fichiers correspondant au pattern # -g '!*.txt' rechercher dans les fichiers ne correspondant pas au pattern # -c count the matched lines per matching file # search in pdf rg --pre ripgrep-preprocess-pdf.sh --pre-glob '*.pdf' [occurence] |
ripgrep-preprocess-pdf.sh |
#!/bin/bash set -e set -o pipefail set -u if [ -s "$1" ]; then exec pdftotext - - else exec cat fi |
grep
# rechercher les lignes qui commencent par # ... | grep ^# # rechercher les lignes qui ne commencent par # ... | grep -v ^# # rechercher les lignes qui se terminent par jpg ... | grep jpg$ # rechercher toutes les occurrences dans les fichiers d'un dossier grep -rin occurence /chemin # -r Read all files under each directory, recursively, following symbolic links only if they are on the command line. # -R Read all files under each directory, recursively. Follow all symbolic links, unlike -r. # -i case insensitive # -n Prefix each line of output with the line number within its input file. # -H Print the file name for each match. # -C 5 affiche 5 lignes avant et après les correspondances # --exclude-dir={.git,.svn,CVS} # support des expressions rationnelles étendues POSIX : # les opérateurs {}, (), +, | et ? n'ont plus besoin d'être échappés ... | grep -E 'http://[a-zA-Z0-9._/]+\.jpg' # retourne seulement l'expression rationnelle et non toute la ligne ... | grep -Eo 'http://[a-zA-Z0-9._/]+\.jpg' # pour les assertions look-behind, utiliser Perl-compatible regular expression (PCRE) au lieu de extended regular expression (ERE) grep -Po '(?<=Version )[[:digit:]]+.[[:digit:]]+' # test la valeur de retour de grep if ! mount | grep -q /media/xxx; then sshfs user@xxx:/home/user /media/xxx fi # -q: quiet, ne rien écrire sur stdout # si une correspondance est trouvée, retourne 0 et valide le test # si aucune correspondance n'est trouvée, retourne 1 et ne valide pas le test |
egrep → grep -E Interpret PATTERNS as extended regular expressions fgrep → grep -F Interpret PATTERNS as fixed strings, not regular expressions |
cut
Découpe une chaîne de caractères
# découpe suivant le caractère , et sélection de la seconde partie echo "123,456,789" | cut -d , -f2 # 456 # espace comme délimiteur cut -d ' ' |
awk
Fonction de filtre.
# Afficher la colonne 9 du résultat de la commande ls ls -l | awk '{ print $9 }' # Afficher les colonnes 6 jusqu'à la dernière du résultat de la commande ls # en espaçant les colonnes par un espace. ls -l | awk '{ for (i=6; i<NF; i++) printf "%s ", $i ; print $NF }' # Passer une variable (premier argument $1) à awk awk -v vawk="$1" '$0 ~ vawk ... ' # Exemple: recherche xxx dans les fichiers du dossier courant find . -type f -exec awk -v vawk=xxx '$0 ~ vawk {c++} c>0 {print ARGV[1] ; exit 0 } END { if (! c) {exit 1}}' '{}' ';' # BEGIN - END who | awk 'BEGIN { printf "(" } { printf "%s", $1 } END { printf ")\n" }' # Exécuter une commande système ls -l | awk '{ system("commande bash"$1); print ...; }' # Exécuter une commande système et en récupérer le résultat # (compter le nombre d'espace dans chaque ligne) ls -l | awk '{ cmd = "echo "$0" | tr \" \" \"\n\" | wc -l" cmd | getline nbSpaces close(cmd) if (nbSpaces == 8) print ...; else print ...; }' # connaître le numéro de la ligne correspondant à une occurrence awk '/occurence/{ print NR; exit }' fichier.txt |
|
FS | input Field Separator (espace par défaut) |
OFS | Output Field Separator (espace par défaut) |
RS | input Record Separator (retour à la ligne par défaut) |
ORS | Output Record Separator (retour à la ligne par défaut) |
NR | Number of Records being processed |
NF | Number of Fields in the current record |
sed (Stream EDitor)
regex
[0-9] [[:digit:]] | chiffre, \d n'existe pas |
\s | espace, tab |
\w | character [0-9a-zA-Z_] |
- Mode basic regex, échapper ? + { } , \( \) sont utilisés pour les groupes
- Mode extended regex -r, échapper ( ) car utilisés pour les groupes
Remplacer du texte
Manipulation de chaînes de caractères permettant de remplacer des occurrences dans un flux de texte.
# remplacer des occurrences dans un fichier texte sed "s/occurrence à remplacer/texte de substitution/drapeaux" -i fichier-cible.txt # dry run: afficher la sortie au lieu de remplacer dans le fichier sed "s/occurrence à remplacer/texte de substitution/drapeaux" fichier-cible.txt # utilisation des groupes sed "s/\(groupe 1\) \(groupe 2\)/\1 \2/" -i fichier-cible.txt # caractères spéciaux sed "s/[0-9]\+\.[0-9]\{1,2\}/ /" -i fichier-cible.txt # utiliser les simples quotes et un autre signe de séparation : # sed 's#occurrence à remplacer#texte de substitution#drapeaux' -i fichier-cible.txt # échapper des simples quotes echo 'texte' | sed 's/occurrence à remplacer avec un simple quote \x27/texte de substitution/' # Exemples # ajouter un \ à la fin de chaque lignes sed 's/$/\\/' fichier.txt # échapper un backslash echo '123\\456' | sed 's/\\/+/' echo '123\\456' | sed "s/\\\\/+/" # multiple replace sed 's/regex1/txt1/; s/regex2/txt2/;' fichier.txt sed ' s/regex1/txt1/ s/regex2/txt2/' \ -i fichier.txt |
Drapeaux :
- g (global) : remplacement de toutes les occurrences, par défaut seule la première est remplacée
- I (case-Insensitive)
- M (Multi lines) : ^ et $ désignent respectivement le debut et la fin d'une ligne, par défaut ils désignent le début et la fin du flux de texte.
Il est possible d'utiliser un autre caractère de séparation que / au cas où celui-ci serait déjà présent dans le texte et qu'il serait impossible ou fastidieux à échapper.sed -i "s|aaa|bbb|" fichier |
sed fait un traitement ligne par ligne, dans le cas d'une expression rationnelle sur plusieurs lignes envisager un autre outils. |
Dans le cas où le texte de remplacement contiendrait un retour à la ligne
|
Extraire du texte
# récupère la ligne 'regex (groupe) regex' et extrait 'groupe' sed -n -r 's/regex (groupe) regex/\1/p' fichier.txt # -n: suppress automatic printing of pattern space # -r: use extended regular expressions such as \1 # use grep grep -Eo 'regex' # -E: interpret PATTERN as an extended regular expression # -o: print only the matched (non-empty) parts of a matching line |
Insérer du texte
# insérer avant la correspondance sed '/regex/i texte à insérer' -i fichier.txt # insérer après la correspondance sed '/regex/a texte à insérer' -i fichier.txt # insérer après la correspondance sed '/regex/i \ texte\ multi-lignes' -i fichier.txt # insérer à la deuxième ligne sed '2i texte à insérer' -i fichier.txt # modifier le fichier sed '/regex/i texte à insérer' -i fichier.txt # modifier le fichier et créer un fichier *.bak sed '/regex/i texte à insérer' -i.bak fichier.txt |
Supprimer des lignes
# supprimer une ligne entière sed '/occurrence de la ligne a supprimer/d' -i fichier.txt sed '\|occurrence de la ligne a supprimer|d' -i fichier.txt # supprimer la première ligne du fichier sed '1d' -i fichier-cible.txt # supprimer la première et la dernière lignes du fichier sed '1d;$d' -i fichier.txt # supprimer les lignes 2 à 4 du fichier sed '2,4d' -i fichier.txt # supprimer toutes les lignes du fichier sauf la première sed '1!d' -i fichier.txt # récupérer la ligne d'une occurrence et supprimer un bloc de 5 lignes line_number_to_delete=$(awk '/occurrence/{ print NR; exit }' fichier.txt) if [ -n "${line_number_to_delete}" ] && (( line_number_to_delete != 0 )); then sed "$line_number_to_delete,$(( line_number_to_delete + 5 ))d" -i fichier.txt fi |
Erreurs
sed: couldn't open temporary file /path/sedlCpwu7: Permission denied
sed doit avoir les droits d'écriture dans le dossier du fichier à modifier pour créer un fichier temporaire.
# solution maunelle sed '2i text' /path/file > /tmp/file cat /tmp/file > /path/file rm /tmp/file |
wc
Compte le nombre de lignes, de mots, de caractères
# Compte le nombre de lignes renvoyé par la commande ps -e | grep X ps -e | grep X | wc -l # nombre de lignes du fichier « mon-fichier.txt » echo $(wc -l < mon-fichier.txt) # Compte le nombre de caractères avec le \0 de fin de mot echo "123" | wc -m # 4 |
tr
Remplacement caractère par caractère.
# compter le nombre d'espace echo 'un petit texte' | tr ' ' '\n' | wc -l |
tail
# Affiche au fur et à mesure les lignes ajoutées au fichier tail -f fichier.log # fonctionne aussi avec plusieurs fichiers en même temps # Affiche les 10 dernières lignes d'un fichier tail fichier.txt # Supprime les 4 premières lignes d'un fichier tail -n +5 fichier.txt > fichier_réduit.txt |
head
# affiche les 5 premières lignes de la sortie ls -at | head -n 5 |
tac
Inverse de cat: affiche le contenu d'un fichier de la dernière ligne à la première.
rev
Lit les lignes à l'envers
cat mon-fichier.txt | rev |
paste
Concaténation de 2 fichiers ligne par ligne
paste 1.txt 2.txt -d ';' # -d séparateur # 1;un # 2;deux |
jq
Manipulation de donnée JSON.
# affichage avec coloration syntaxique echo '{"un":"1","deux":"2"}' | jq # requête echo '{"un":"1","deux":"2"}' | jq .deux # "2" # affichage brut (raw) echo '{"un":"1","deux":"2"}' | jq -r .deux # 2 # afficher toutes les values echo '{"un":"1","deux":"2"}' | jq '.[]' # "1" "2" # afficher toutes les keys echo '{"un":"1","deux":"2"}' | jq 'keys | .[]' # "deux" "un" # lancer une commande pour chaque élément jq -r '.backup | .[]' backup_pc_folders.json | \ xargs -I '{}' -P 4 -t bash -c "echo '{}'" jq -r '.backup | .[]' backup_folders.json | while read -r folder; do echo $folder done jq -r '.[]|[.name, .value] | @tsv' MyAppSettings.json | while IFS=$'\t' read -r name value; do echo $name - $value done # stocker le résultat dans un tableau IFS=$'\n' read -r -d '' -a my_array < <(jq -r '.key | .[]' file.json && printf '\0') |
sort
Trie la sortie d'une commande
# Trie la liste des fonts en ignorant la casse fc-list : family | sort -f # 08 juin 2013 - texte sort -k 3,3 -k 2M -k 1 # trie par rapport à l'année -k 3,3 # puis trie par rapport au mois -k 2M # enfin trie par rapport au jour -k 1 du -h dossier | sort -h |
- -f → ignore la casse
- -M → comparer les mois
- -r → inverse les résultats
- -k → trie par rapport à un élément
- --debug → affiche l'élément qui a servit au trie
- -h, --human-numeric-sort → compare human readable numbers (e.g., 2K 1G)
- -R, --random-sort → mélange aléatoirement au lieu de trier
Manipulation de fichiers / dossiers
cd
# retour dans le dossier précédent cd - |
ls
-a | do not ignore entries starting with . |
-A | do not list implied . and .. |
-l | use a long listing format |
-o | like -l, but do not list group information |
-r | reverse order while sorting |
-t | sort by modification time, newest first |
-S | sort by file size, largest first |
-h | print human readable sizes |
# lister les dossiers seulement ls -d */ | cut -f1 -d'/' # lister les fichiers par taille ls -lhS # lister les fichiers par date, le plus récent en premier ls -thor |
exa
Modern replacement for ls.
# -1: display one entry per line exa -1 --icons # -l: display extended file metadata as a table # -g: list each file’s group exa -lg --icons # -a: show hidden and “dot” files. Use this twice to also show the `.' and `..' directories exa -lgaa --icons |
mv
# copie /chemin1/dossier1 dans /chemin2/dossier2 mv /chemin1/dossier1 /chemin2/dossier2 # /chemin2/dossier2/dossier1 # copie /chemin1/dossier1 dans /chemin2 et le renomme dossier2 mv -T /chemin1/dossier1 /chemin2/dossier2 # /chemin2/dossier2 |
cp
# copie de folder1 dans folder2 cp -r /folder1 /folder2 # si folder2 existe déjà, folder1 est copié dans folder2 (/folder2/folder1) # si folder2 n'existe pas, folder2 est créé et contient le même contenu que folder1 # si folder2 existe déjà et que l'on veut copier le contenu de folder1 dans folder2 cp -r /folder1/. /folder2 # -f to overwrite without asking |
rm
# remove all files except file1.txt and file2.txt shopt -s extglob rm -i !(file1|file2).txt shopt -u extglob # zsh setopt extended_glob rm -i -- ^(file1|file2).txt |
trash-cli
# move a file to the trash trash-put [filename] # display the content of the trash and allow to select which files to restore trash-restore # empty the trash trash-empty # list the content of the trash trash-list |
fd
fd [-HIEsiaLp0hV] [-d depth] [-t filetype] [-e ext] [-E exclude] [-c when] [-j num] [-x cmd] [pattern] [path]
# extension fd -e png # regex fd '^\w{2,3}\.json$' # type: Fichier, Dossier, symLink, eXecutable, Empty fd -t f # fichiers et dossiers cachés fd -H xxx # ignore les exclusions de git (.gitignore) et fd (.fdignore) fd -I xxx # exclure fd '*.bak' -E /mnt/external-drive # execute command -x: for each match, -X: for all matches as parameters fd -t f '^\w{2,3}(-\w+)?\.json$' -E fr.json -E en.json -X rm -f |
fd peut être masqué par le plugin zsh common-aliases (fichier ~/.oh-my-zsh/plugins/common-aliases/common-aliases.plugin.zsh) |
find
# Recherche d'un fichier commençant par libpcre dans / find / -name 'libpcre*' # ne pas afficher les messages Permission denied find / -name 'libpcre*' 2>&1 | grep -v 'Permission denied' # Lister tous les dossiers avec une profondeur d'exploration de 1 (pas de sous-dossiers) find / -maxdepth 1 -type d # Recherche tous les fichiers dont les extensions sont so ou exe find . -name '*.exe' -or -name '*.so' find . -regex '.*\(so\|exe\)$' # regex prend en compte le chemin complet et pas seulement le nom de fichier, c'est pourquoi il commence par .* # Recherche tous les fichiers dont les extensions ne sont ni so ni exe find . \! -name '*.exe' \! -name '*.so' # supprimer tous les fichiers *.gz de plus de 7 jours find . -type f -mtime +7 -name '*.gz' -delete # Rechercher tous les fichiers contenant l'expression rationnelle find . -type f -exec awk '/regex/ {c++} c>0 {print ARGV[1] ; exit 0 } END { if (! c) {exit 1}}' \{\} \; # rechercher tous les fichiers qui viennent d'être modifiés find / -type f -ls -mmin -1 # -mmin -1 : modifiés depuis 1 minute ou moins |
diff
# create the diff file diff -u /path1/file1.txt /path2/file2.txt > /path3/patch.diff # apply the patch patch /path1/file1.txt < /path3/patch.diff |
Disc usage
df
Displays the amount of space available on the file systems
df -hl -x tmpfs -x devtmpfs -x overlay # -h print sizes in powers of 1024 (e.g., 1023M) # -l limit listing to local file systems # -x limit listing to file systems not of type TYPE |
du
- -s, --summarize : display only a total for each argument
- -h, --human-readable: print sizes in human readable format (e.g., 1K 234M 2G)
# taille du dossier du -hs dossier |
dust
# display the size of the bigest folders and their bigest content (21 directories/lines by default) dust -br /path # -b do not show percentages or draw ASCII bars # -r reverse order of output, with root at the lowest # display the size of all the folders dust -brd 1 /path # -d 1 shows 1 level of subdirectories + remove restriction on the number of directories/lines displayed # display the size of the bigest folders and their bigest content (10 directories/lines) dust -brn 10 /path # -n 10 shows 10 directories/lines instead of the 21 default # install cargo install du-dust |
chmod
# chmod [ugo][+-][rwxXst] fichier-ou-dossier # X get execute rights only to directories and to files which already have execute permission for some user # forcer les droits u:rw g:r o:r chmod 644 fichier-ou-dossier # ajouter le droit write au propriétaire chmod u+w fichier-ou-dossier # supprimer tous les droits write à tous les éléments d'un répertoire # (non récursif et ne s'applique pas au répertoire) chmod -w dossier/* # supprimer tous les droits write à tous les éléments d'un répertoire # (récursif et s'applique aussi au répertoire) chmod -R -w dossier # donne au groupe les mêmes droits que ceux de l'utilisateur chmod g=u fichier-ou-dossier # modifiez les droits de tous les dossiers sans toucher aux fichiers find /chemin/vers/un/dossier/ -type d -print0 | xargs -0 chmod 755 # modifiez les droits de tous les fichiers sans toucher aux dossiers find /chemin/vers/un/dossier/ -type f -print0 | xargs -0 chmod 644 |
suid | s à la place du x du propriétaire: rwsr-xr-x → 4755 (suid=4) | Un programme lancé avec ce droit suid sera exécuté avec les droits du propriétaire du programme et non les droits de l'utilisateur qui l'a lancé. |
sgid | s à la place du x du groupe: rwxr-sr-x → 2755 (sgid=2) | Un programme lancé avec ce droit sgid sera exécuté avec les droits du groupe du programme et non les droits du groupe de l'utilisateur qui l'a lancé. Les fichiers nouvellement créés auront le goup id du dossier. |
stiky bit | t à la place du x des autres: rwxr-xr-t → 1755 (stiky bit=1) | Dans un répertoire avec ce droit stiky bit, seuls les propriétaires des fichiers pourront les effacer. |
S'il n'y avait pas de droit d'exécution x avant d'appliquer ces droits, les lettres s et t seront mises en majuscule. |
chown
chown user:group fichier-ou-dossier # -R mode récursif # -h modifie les liens symboliques plutôt que les cibles des liens # change le propriétaire si celui-ci est 1000 chown --from=1000:1000 root:root fichier-ou-dossier |
chgrp
chgrp group fichier-ou-dossier # équivalent à chown :group fichier-ou-dossier |
ACL - Access Control Lists
# lister les ACL getfacl /path # ajoute les droits rw pour l'utilisateur myuser récursivement dans le dossier /path/folder setfacl -R -m u:myuser:rw /path/folder # -m (--modify) # ajoute les droits rwx pour le groupe mygroup récursivement dans le dossier /path/folder setfacl -R -m g:mygroup:rwx /path/folder # remove all extended ACL entries setfacl -b /path/folder |
Connaitre le type MIME d'un fichier
xdg-mime query filetype fichier.ext # image/jpeg file -b -i fichier.ext # image/jpeg; charset=binary |
bat
A cat clone with syntax highlighting and Git integration.
bat /path/file.ext |
.zshenv |
# use bat as a colorizing pager for man export MANPAGER="sh -c 'col -bx | bat -l man -p'" |
Archivage
tar
# extrait une archive dans le dossier courant, tar devine le bon décompresseur tar xvf archive.tar.gz # extrait une archive dans /mon_dossier tar xvf archive.tar.gz -C /mon_dossier # créer une archive tar.gz contenant des fichiers tar czf Archive.tar.gz fichier1.txt fichier2.txt *.sh # créé une archive tar.gz à partir de mon_dossier tar cvzf archive.tar.gz mon_dossier # créé une archive tar.gz à partir de mon_dossier en excluant le contenus de mon_sous_dossier1 et mon_sous_dossier2 tar cvzf archive.tar.gz --exclude={mon_dossier/mon_sous_dossier1/*,mon_dossier/mon_sous_dossier2/*} mon_dossier # créé une archive tar.gz et supprimer les fichiers archivés tar cvzf archive.tar.gz fichier1.ext fichier2.ext --remove-files # créer une archive tar tar cf MonDossier.tar MonDossier tar cf Fichiers.tar fichier1.txt fichier2.txt *.sh # créer une archive tar.7z tar cf - MonDossier | 7z a -si MonDossier.tar.7z # multithreads avec pigz tar cf Archive.tar.gz -I pigz Dossier1 Dossier2 Fichier1 tar cf - Dossier1 Dossier2 Fichier1 | pigz > Archive.tar.gz # désarchiver tar xf Archive.tar.gz -I pigz # encrypter l'archive tar cf - MonDossier | pigz | openssl aes-256-cbc -pass pass:mon_mot_de_passe > MonDossier.tar.gz.enc # décrypter l'archive openssl aes-256-cbc -d -pass pass:mon_mot_de_passe -in MonDossier.tar.gz.enc | tar -xz -f - |
- x : extract files from an archive
- c : create archive from files
- f : use archive file
- v : verbosely list files processed
- z : gzip
- j : bzip (bz2)
- --exclude-vcs : exclude Version Control System like .git
tar peut deviner le décompresseur à utiliser (gzip, bzip, etc). Il n'est donc pas nécessaire de spécifier les options correspondantes (z, j) |
gzip est plus rapide que bzip2 mais compresse moins. |
Suppression de « / » au début des noms des membres
tar supprime le « / » au début des noms de dossiers et fichiers à archiver. Ceci afin d'éviter d'écraser des dossiers et fichiers systèmes lors de la décompression. Pour éviter ce comportement, il faut utiliser des chemins relatifs au lieu de chemins absolus.
unzip
unzip fichier.zip # -q dézippe silencieusement sans afficher dans le détail tous les fichiers qui sont créés |
gzip
# décompresser une archive dans le même dossier gzip -dk archive.gz # -k : keep the archive, sinon elle est supprimée par défaut # décompresser une archive avec choix de la destination gzip -dkc archive.gz > /ailleurs/fichier # créer une archive gzip -k fichier.txt # -k : conserver fichier.txt, sinon il est supprimé |
gzip ne peut compresser qu'un seul fichier. C'est pourquoi il est utilisé en combinaison avec tar |
7zip
# create an archive with folder1 and file1.ext 7z a archive.7z folder1 file1.ext # -p to ask for a password # -tzip to create a zip instead of of 7z # désarchiver (-o: change the output folder) 7z x MonArchive.7z -oFolder # désarchiver et renommer le fichier (-so: standard output). Peut créer un problème d'encoding. 7z x MonArchive.7z -so > file.ext # créez une archive tar.7z tar cf - MonDossier | 7z a -si MonDossier.tar.7z # extraire le contenu d'une archive tar.7z 7z x -so MonDossier.tar.7z | tar xf - |
Avec Cygwin:
seven-zip=$(cygpath -u "C:\Program Files\7-Zip\7z.exe") "$seven-zip" a -tzip archive.zip Dossier Fichier.ext |
Les archives zip avec un cryptage AES-256 et un mot de passe ne peuvent être déchiffrées nativement sous Windows |
pigz
# compress pigz file.txt # file.txt.gz pigz -c file.txt > archive.gz # uncompress pigz -d file.txt.gz # options # -k keep source file # -z compress to zlib (.zz) instead of gzip # -K compress to zip instead of gzip # --best / -9 best and slowest compression # --fast / -0 fastest and lowest compression # -c write to stdout (won't delete) # compress directory tar cf - directory/ | pigz > directory.tar.gz tar --use-compress-program=pigz -cf directory.tar.gz directory/ |
Network
wget
# Télécharger un fichier wget http://...MonFichier.ext # Télécharger un fichier et choisir le dossier de destination wget http://...MonFichier.ext -P /path # Renommez le fichier téléchargé wget http://...MonFichier.ext -0 chemin/AutreNom.ext # Affichez le contenu du fichier dans la sortie standard wget http://...MonFichier.ext -0 - # Téléchargez toutes les images jpg et gif d'un site # Dans ce cas le mode récursif ne marchera pas car les fichiers html ou php ne seront pas téléchargés wget -m -A jpg,gif http://site.fr/ # Téléchargez récursivement le contenu de dossier sans remonter au répertoire parent wget -r -np http://site.fr/dossier/ # test si le fichier existe wget --spider -q http://...MonFichier.ext if [ $? == 0 ] # en 1 ligne wget --spider -q http://...MonFichier.ext && echo ok || echo ko |
-P | Set directory prefix to prefix, default is . (the current directory). |
--max-redirect=0 | empèche les redirection 302 Moved Temporarily |
--no-verbose | réduit les commentaires de sortie |
-q | pas d'affichage en sortie |
--referer= | spécifie l'url de la page qui demande le téléchargement du fichier |
-e robots=off | ignorer les instructions du fichier robots.txt |
-np | ne pas récupérer des éléments du dossier parent |
--user-agent= | faire passer wget pour un navigateur web Firefox - Linux 32 : Mozilla/5.0 (X11; Linux i686; rv:20.0) Gecko/20100101 Firefox/20.0 |
--limit-rate=50k | limite la vitesse de téléchargement |
-nd | dans le cas d'un téléchargement récursif, pas de création de la hiérarchie de dossiers |
EXIT STATUS 0 No problems occurred. 1 Generic error code. 2 Parse error---for instance, when parsing command-line options, the .wgetrc or .netrc... 3 File I/O error. 4 Network failure. 5 SSL verification failure. 6 Username/password authentication failure. 7 Protocol errors. 8 Server issued an error response.
curl
curl http://www.domain.fr/file.txt > file.txt |
Récupérer la commande curl équivalente: Firefox → Ctrl+Shift+q (Network in Developer Tools) → Reload |
Autres
date
date +%Y-%m-%d # 2020-01-30 date -d "yesterday" +%Y-%m-%d # 2020-01-29 |
secret-tool
Accès à Gnome Keyring
# enregistrer un mot de passe avec le label MySQL et les clé→valeur server→mysql user→root key→password secret-tool store --label='MySQL' server mysql user root key password # les clé→valeur serviront par la suite à la récupération du mot de passe # récupération du mot de passe avec les clé→valeur server→mysql user→root key→password secret-tool lookup server mysql user root key password |
Si plusieurs entrées correspondent aux clé→valeur, la première est retournée. |
xdotool
# Control+v puis Entrée xdotool key ctrl+v Return # Control+v # délai de 0ms (au lieu de 12ms) entre l'appui des touches # les modificateur ctrl, alt, super sont ignorés xdotool key --delay 0 --clearmodifiers ctrl+v # alt + tab xdotool keydown alt key Tab; sleep .1; xdotool keyup alt # bouton 1 de la sourie xdotool click 1 # target a specific window xdotool search --class 'My window class' windowactivate --sync key Right # windowactivate --sync active the window and wait until it is activated # --onlyvisible search only among displayable windows. Useful when the search retrieves multiple results with undisplayable windows. |
Use xprop to get info on a window (name, class) |
Détacher un processus
Cela permet de fermer le terminal en laissant le processus tourner.
nohup [commande] & # si le processus est déjà lancé # le mettre en pause: Ctrl-Z # le faire tourner en background bg # puis détacher le processsus disown |
Clipboard
# copie test dans le presse papier echo test | xclip -selection clipboard # copie test dans le presse papier du bouton du milieu echo test | xclip # copie d'un fichier binaire cat photo.png | base64 | xclip # coller echo '# clique-milieu pour coller ' | base64 -d > photo.png |
rsvg-convert
Convertir une image SVG en PNG
rsvg-convert -w $size -h $size fichier.svg > fichier.png |
FTP
Les options de ftp : v → verbeux, n → désactive auto-login (lecture d'informations dans le fichier ~/.netrc)
#!/bin/bash ftp -vn << EOF open bananeatomic.free.fr quote user bananeatomic quote pass **** cd dossier_destination passive ascii put chemin_fichier_local [chemin_fichier_destination] bye EOF |
hl - Highlight (colorize) text data using regular expressions
# coloration en rouge de texte echo "un petit texte" | hl -3r texte # utilisation d'expression rationnelle: coloration en vert des mots qui contiennent un e echo "un petit texte" | hl -e -3g '\<\w*e\w*\>' # utilisation de la configuration (/etc/default/hl) df -h | hl --df # désactiver la colorisation des commandes colorisées USE_HL=no df -h # installation yay --editmenu -S hl-git # in PKGBUILD remove lines 25 and 26 # sed "s/inline //g" -i cr_main.c |
/etc/default/hl |
pacman : -e -3g '^\S[^/]+/([^ ]+)' |
Pour faciliter la coloration, des scripts encapsulent les commandes à colorer. Ces scripts sont placés dans /usr/lib/hl_bin et PATH est modifié pour que les nouveaux scripts aient la préséance sur les commandes. |
tput: add color in terminal
echo -e "$(tput bold; tput setaf 3;)\n= Title =\n$(tput sgr0)" |
Capname | Description |
---|---|
bold | start bold text |
smul | start underlined text |
rmul | end underlined text |
setaf | set foreground color |
setab | set background color |
sgr0 | turn off all attributes |
Color | Code |
---|---|
black | 0 |
red | 1 |
green | 2 |
yellow | 3 |
blue | 4 |
magenta | 5 |
cyan | 6 |
white | 7 |
default | 9 |
sleep, timeout
# arrête le programme pendant 1 seconde sleep 1 && echo ok # définit un temps d'attente max timeout 1 sleep 2 && echo ok || echo ko # code de retour: 124 (timeout), 0 (ok) |
Parallel
Allow to run commands in parallel. The GNU Parallel tool needs to be installed.
# list all mp4, then remove extension, then add avi extension ls *.mp4 | sed -n 's/\.mp4$//p' | parallel echo "{}.avi" |
tldr
Simplified and community-driven man pages with practical examples.
tldr [command] |
XML with xmlstarlet
# replace: edit update xml ed -u "/query" --value "new value" file.xml |
Global option | Description |
---|---|
L | edit file inplace |
S | preserve non-significant spaces |
O | omit XML declaration (<?xml ...?>) |
script / scriptreplay
# record the command output script -q -c '[command]' [output-file] # -q, --quiet: do not write start and done messages to standard output # display the command output cat [output-file] # record the script interaction script -T [time-file] [output-file] # -T, --log-timing [time-file]: log timing information to the file # replay the script interaction scriptreplay -t [time-file] [output-file] # -t, --timing [time-file]: file containing script's timing output |