Comment obtenir les chemins relatifs avec ls?

8

Je voudrais faire quelque chose comme ça pour déplacer les deux derniers fichiers téléchargés:

mv ` ls -rt ~/Downloads/ | tail -2 ` .

Malheureusement, lsne donne que les noms de fichiers. Comment puis-je adapter le code ci-dessus?

(Avant que quelqu'un ne le signale, je suis conscient des problèmes de canalisation de la sortie de ls. Je n'utiliserais cela que lorsque je connais les noms de fichiers en question.)

Tim
la source
9
Utilisez findplutôt.
Ignacio Vazquez-Abrams

Réponses:

10

D'accord, donc si vous n'abandonnez pas ls, essayez au moins de sortir de l'habitude d'utiliser des backticks pour tout, surtout quand xargsc'est mieux:

ls -rtd ~/Downloads/* | tail -n2 | xargs -I{} mv {} .
géocar
la source
Votre xargsme plaît plus que les backticks. Mais y a-t-il une raison technique de préférer cette séquence de pipes et xargsplutôt que l'utilisation de backticks ou n'est-ce qu'une question de goût?
miracle173
Dans ce cas, nous ne regardons que deux fichiers, mais si nous voulions déplacer des milliers de fichiers, nous pourrions accidentellement essayer de créer une ligne de commande trop longue.
geocar
Aussi: dans le cas de centaines de fichiers, nous pouvons commencer à travailler immédiatement. Avec les backticks, nous devons attendre la fin de la sous-commande.
geocar
Aussi: Lorsque vous réussissez à lsvous xargs -0
débarrasser de
3
L'analyse lsest déconseillée: mywiki.wooledge.org/ParsingLs
Gilles Quenot
8

Vous pouvez y utiliser GNU find:

mv $(find ~/Download -mindepth 1 -maxdepth 1 -printf '%Ts %p\n' | sort -n | cut -d ' ' -f2- | tail -n 2) .

Les find -printfoptions:

  • %Tspour afficher l'heure comme époque
  • %p le chemin du fichier

Voir man find | less +/'^ *-printf'

Éditer

si vous avez besoin de gérer les espaces dans les noms de fichiers, je recommande cette autre solution:

find -maxdepth 1 -printf '%Ts %p\n' |
    sort -n |
    cut -d ' ' -f2- |
    tail -n 2 |
    xargs -i% mv % .
Gilles Quenot
la source
Ajout d'explications sur les find -printfoptions
Gilles Quenot
1
Je suis curieux: y a-t-il une raison particulière d'utiliser -f2-au lieu de -f2comme option cut? À quoi sert le deuxième tiret?
Francesco Turco
1
Bien sûr Francesco Turco, comme dit man cut, il imprime jusqu'à la fin s'il y a plus d'un col.
Gilles Quenot
POST modifié pour fonctionner avec des noms de fichiers avec des espaces.
Gilles Quenot
3

Utilisez ls -rt ~/Downloads/*au lieu de ls -rt ~/Downloads/. Dans ls -rt ~/Downloads/*l'argument, la chaîne est d'abord développée par le shell (cela s'appelle la globalisation du nom de fichier ). Vous obtenez donc une liste de chemins comme arguments pour la ls -rtcommande, qui la trie ensuite de la manière que vous spécifiez par les options de ls. En revanche, la commande ls -rt ~/Downloads/lit le contenu du répertoire ~/Downloads/. Il s'agit d'une liste de fichiers sans le chemin du répertoire.

miracle173
la source
2

Avec zsh:

mv ~/Downloads/*(.om[1,2]) .

Les (...)pièces sont appelées qualificatifs globbing , l'une des caractéristiques les plus importantes de zsh. Chaque qualificatif (généralement des caractères uniques) permet de filtrer les entrées correspondantes en fonction des attributs des fichiers (type, taille, heure ...), de modifier l'ordre dans lequel ils sont développés ou de modifier la façon dont ils sont développés.

Ci-dessus, nous avons:

  • . (point): sélectionnez uniquement les fichiers standard (pas les répertoires, les liens symboliques ...)
  • om: O rder la liste par m temps de odification.
  • [1,2]: sélectionnez uniquement les deux premières entrées.

Notez également que la commande échouera s'il n'y a pas de correspondance (où d'autres shells pourraient accidentellement déplacer le mauvais fichier / dir).

Stéphane Chazelas
la source