Alleen mappen weergeven die ls gebruiken in Bash?

Dit commando geeft mappen weer in het huidige pad: ls -d */

Wat doet het patroon */ precies?

En hoe kunnen we het absolute pad in het bovenstaande commando geven (bijv. ls -d /home/alice/Documents) om alleen mappen in dat pad weer te geven?


Antwoord 1, autoriteit 100%

*/ is een patroon dat overeenkomt met alle submappen in de huidige map (* komt overeen met alle bestanden en submappen; de / beperkt het tot mappen). Op dezelfde manier, om alle submappen onder /home/alice/Documents weer te geven, gebruik je ls -d /home/alice/Documents/*/


Antwoord 2, autoriteit 47%

Vier manieren om dit voor elkaar te krijgen, elk met een ander uitvoerformaat

1. echo

gebruiken

Voorbeeld: echo */, echo */*/
Dit is wat ik heb:

cs/ draft/ files/ hacks/ masters/ static/  
cs/code/ files/images/ static/images/ static/stylesheets/  

2. Alleen ls gebruiken

Voorbeeld: ls -d */
Dit is precies wat ik heb:

cs/     files/      masters/  
draft/  hacks/      static/  

Of als lijst (met gedetailleerde info): ls -dl */

3. Gebruik ls en grep

Voorbeeld: ls -l | grep "^d"
Dit is wat ik heb:

drwxr-xr-x  24 h  staff     816 Jun  8 10:55 cs  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 draft  
drwxr-xr-x   9 h  staff     306 Jun  8 10:55 files  
drwxr-xr-x   2 h  staff      68 Jun  9 13:19 hacks  
drwxr-xr-x   6 h  staff     204 Jun  8 10:55 masters  
drwxr-xr-x   4 h  staff     136 Jun  8 10:55 static  

4. Bash-script (niet aanbevolen voor bestandsnamen die spaties bevatten)

Voorbeeld: for i in $(ls -d */); do echo ${i%%/}; done
Dit is wat ik heb:

cs  
draft  
files  
hacks  
masters  
static

Als je ‘/’ als eindteken wilt hebben, is het commando: for i in $(ls -d */); do echo ${i}; done

cs/  
draft/  
files/  
hacks/  
masters/  
static/

Antwoord 3, autoriteit 10%

Ik gebruik:

ls -d */ | cut -f1 -d'/'

Hiermee wordt een enkele kolom gemaakt zonder een schuine streep aan het einde – handig in scripts.


Antwoord 4, autoriteit 6%

Voor alle mappen zonder submappen:

find /home/alice/Documents -maxdepth 1 -type d

Voor alle mappen met submappen:

find /home/alice/Documents -type d

Antwoord 5, autoriteit 4%

Vier (meer) betrouwbare opties.

Een niet aangehaalde asterisk * wordt door de shell geïnterpreteerd als een patroon (glob). De shell zal het gebruiken bij padnaamuitbreiding. Het genereert dan een lijst met bestandsnamen die overeenkomen met het patroon.

Een eenvoudig sterretje komt overeen met alle bestandsnamen in de PWD (huidige werkmap). Een complexer patroon als */ komt overeen met alle bestandsnamen die eindigen op /. Dus alle mappen. Daarom het commando:

1.- echo.

echo */
echo ./*/              ### Avoid misinterpreting filenames like "-e dir"

wordt uitgebreid (door de shell) naar echo alle mappen in de PWD.


Om dit te testen: maak een map (mkdir) aan met de naam test-dir, en cd erin:

mkdir test-dir; cd test-dir

Maak enkele mappen:

mkdir {cs,files,masters,draft,static}   # Safe directories.
mkdir {*,-,--,-v\ var,-h,-n,dir\ with\ spaces}  # Some a bit less secure.
touch -- 'file with spaces' '-a' '-l' 'filename'    # And some files:

Het commando echo ./*/ blijft betrouwbaar, zelfs met oneven benoemde bestanden:

./--/ ./-/ ./*/ ./cs/ ./dir with spaces/ ./draft/ ./files/ ./-h/
./masters/ ./-n/ ./static/ ./-v var/

Maar de spaties in bestandsnamen maken het lezen een beetje verwarrend.


Als in plaats van echo, gebruiken we ls. De shell is nog steeds wat de lijst met bestandsnamen uitbreidt. De shell is de reden om een ​​lijst met mappen in de PWD te krijgen. De optie -d voor ls zorgt ervoor dat het huidige directory-item wordt weergegeven in plaats van de inhoud van elke directory (zoals standaard weergegeven).

ls -d */

Dit commando is echter (iets) minder betrouwbaar. Het zal mislukken met de oneven benoemde bestanden die hierboven worden vermeld. Het zal stikken met verschillende namen. Je moet één voor één wissen totdat je degene met problemen vindt.

2.- ls

De GNU ls accepteert de toets “einde van opties” (--).

ls -d ./*/                     ### More reliable BSD ls
ls -d -- */                    ### More reliable GNU ls

3.-printf

Om elke directory op zijn eigen regel te vermelden (in één kolom, vergelijkbaar met ls -1), gebruik:

$ printf "%s\n" */        ### Correct even with "-", spaces or newlines.

En, nog beter, we zouden de achterliggende / kunnen verwijderen:

$ set -- */; printf "%s\n" "${@%/}"        ### Correct with spaces and newlines.

Een poging zoals

$ for i in $(ls -d */); do echo ${i%%/}; done

zal mislukken op:

  • enkele namen (ls -d */) zoals hierboven al getoond.
  • wordt beïnvloed door de waarde van IFS.
  • zal namen op spaties en tabs splitsen (met standaard IFS).
  • elke nieuwe regel in de naam start een nieuw echo-commando.

4.- Functie

Ten slotte heeft het gebruik van de lijst met argumenten binnen een functie geen invloed op de lijst met argumenten van de huidige actieve shell. Gewoon

$ listdirs(){ set -- */; printf "%s\n" "${@%/}"; }
$ listdirs

presenteert deze lijst:

--
-
*
cs
dir with spaces
draft
files
-h
masters
-n
static
-v var

Deze opties zijn veilig met verschillende soorten oneven bestandsnamen.


Antwoord 6, autoriteit 2%

De opdracht tree is hier ook erg handig . Standaard toont het alle bestanden en mappen tot een volledige diepte, met enkele ASCII-tekens die de mappenboom tonen.

$ tree
.
+-- config.dat
+-- data
¦   +-- data1.bin
¦   +-- data2.inf
¦   L-- sql
|   ¦   L-- data3.sql
+-- images
¦   +-- background.jpg
¦   +-- icon.gif
¦   L-- logo.jpg
+-- program.exe
L-- readme.txt

Maar als we alleen de mappen wilden krijgen, zonder de ASCII-structuur, en met het volledige pad van de huidige map, zou je het volgende kunnen doen:

$ tree -dfi
.
./data
./data/sql
./images

De argumenten zijn:

-d     List directories only.
-f     Prints the full path prefix for each file.
-i     Makes tree not print the indentation lines, useful when used in conjunction with the -f option.

En als u dan het absolute pad wilt, kunt u beginnen met het opgeven van het volledige pad naar de huidige map:

$ tree -dfi "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/data/sql
/home/alice/Documents/images

En om het aantal submappen te beperken, kunt u het maximale niveau van submappen instellen met -L level, bijvoorbeeld:

$ tree -dfi -L 1 "$(pwd)"
/home/alice/Documents
/home/alice/Documents/data
/home/alice/Documents/images

Meer argumenten zijn te zien met man tree .


Antwoord 7, autoriteit 2%

Voor het geval je je afvraagt ​​waarom uitvoer van ‘ls -d */’ je twee slashes geeft, zoals:

[prompt]$ ls -d */
app//  cgi-bin//  lib//        pub//

waarschijnlijk komt dat doordat ergens in uw shell- of sessieconfiguratiebestanden het ls-commando een alias vormt voor een versie van ls die de vlag -F bevat. Die vlag voegt een teken toe aan elke uitvoernaam (dat is geen gewoon bestand) om aan te geven wat voor soort ding het is. De ene schuine streep komt dus overeen met het patroon ‘*/’ en de andere schuine streep is de toegevoegde type-indicator.

Om van dit probleem af te komen, kunt u natuurlijk een andere alias definiëren voor ls. Om de alias echter tijdelijk niet aan te roepen, kunt u de opdracht toevoegen met een backslash:

\ls -d */

Antwoord 8

Een duidelijke lijst van de huidige map, het zou zijn:

ls -1d */

Als je het gesorteerd en opgeruimd wilt hebben:

ls -1d */ | cut -c 1- | rev | cut -c 2- | rev | sort

Onthoud: tekens met hoofdletters gedragen zich verschillend in de sortering


Antwoord 9

Ik voeg dit gewoon toe aan mijn .bashrc-bestand (je zou het ook gewoon op de opdrachtregel kunnen typen als je het maar voor één sessie nodig hebt/wilt):

alias lsd='ls -ld */'

Vervolgens zal lsd het gewenste resultaat opleveren.


Antwoord 10

Echte ls-oplossing, inclusief symbolische links naar mappen

Veel antwoorden hier gebruiken ls niet (of gebruiken het alleen in de triviale betekenis van ls -d, terwijl ze jokertekens gebruiken voor de daadwerkelijke subdirectory-overeenkomst. Een true ls-oplossing is handig, omdat het het gebruik van ls-opties voor sorteervolgorde, enz. toestaat.

Exclusief symbolische links

Er is één oplossing gegeven die ls gebruikt, maar deze doet iets anders dan de andere oplossingen doordat het symlinks uitsluit naar mappen:

ls -l | grep '^d'

(eventueel door sed of awk geleiden om de bestandsnamen te isoleren)

Inclusief symbolische links

In het (waarschijnlijk vaker voorkomende) geval dat symlinks naar mappen moeten worden opgenomen, kunnen we de optie -p van ls gebruiken, waardoor er een schuine streep aan wordt toegevoegd naar namen van mappen (inclusief gelinkte mappen):

ls -1p | grep '/$'

of, het wegwerken van de slashes:

ls -1p | grep '/$' | sed 's/\/$//'

We kunnen indien nodig opties toevoegen aan ls (als een lange lijst wordt gebruikt, is de -1 niet langer vereist).

Opmerking: als we achterslashes willen, maar niet willen dat ze worden gemarkeerd door grep, kunnen we de markering hackachtig verwijderen door het daadwerkelijk overeenkomende gedeelte van de regel is leeg:

ls -1p | grep -P '(?=/$)'

Antwoord 11

Als een verborgen map niet hoeft te worden vermeld, bied ik het volgende aan:

ls -l | grep "^d" | awk -F" " '{print $9}'

En als verborgen mappen moeten worden weergegeven, gebruik dan:

ls -Al | grep "^d" | awk -F" " '{print $9}'

Of

find -maxdepth 1 -type d | awk -F"./" '{print $2}'

Antwoord 12

Mappenlijsten weergeven zonder /:

ls -d */|sed 's|[/]||g'

Antwoord 13

Alleen voor het weergeven van directories:

ls -l | grep ^d

Voor het weergeven van alleen bestanden:

ls -l | grep -v ^d 

Of je kunt het ook doen als:

ls -ld */

Antwoord 14

Probeer deze eens. Het werkt voor alle Linux-distributies.

ls -ltr | grep drw

Antwoord 15

Dit is wat ik gebruik

ls -d1 /Directory/Path/*;


Antwoord 16

Test of het item een ​​directory is met test -d:

for i in $(ls); do test -d $i && echo $i ; done

Antwoord 17

Ter info, als u alle bestanden in meerdere regels wilt afdrukken, kunt u een ls -1 doen die elk bestand op een aparte regel afdrukt.
bestand1
bestand2
bestand3


Antwoord 18

*/ is een patroon dat overeenkomt met een bestandsnaam dat overeenkomt met mappen in de huidige map.

Om alleen mappen weer te geven, vind ik deze functie leuk:

# Long list only directories
llod () {
  ls -l --color=always "$@" | grep --color=never '^d'
}

Zet het in uw .bashrc-bestand.

Gebruiksvoorbeelden:

llod       # Long listing of all directories in current directory
llod -tr   # Same but in chronological order oldest first
llod -d a* # Limit to directories beginning with letter 'a'
llod -d .* # Limit to hidden directories

Opmerking: het gaat kapot als je de optie -i gebruikt. Hier is een oplossing voor:

# Long list only directories
llod () {
  ls -l --color=always "$@" | egrep --color=never '^d|^[[:digit:]]+ d'
}

Antwoord 19

file * | grep directory

Uitvoer (op mijn computer) —

[root@rhel6 ~]# file * | grep directory
mongo-example-master:    directory
nostarch:                directory
scriptzz:                directory
splunk:                  directory
testdir:                 directory

De bovenstaande uitvoer kan verder worden verfijnd door cut:

te gebruiken

file * | grep directory | cut -d':' -f1
mongo-example-master
nostarch
scriptzz
splunk
testdir
* could be replaced with any path that's permitted
 file - determine file type
 grep - searches for string named directory
 -d - to specify a field delimiter
 -f1 - denotes field 1

Antwoord 20

One-liner om mappen alleen vanaf “hier” weer te geven.

Met aantal bestanden.

for i in `ls -d */`; do g=`find ./$i -type f -print| wc -l`; echo "Directory $i contains $g files."; done

Antwoord 21

Perl gebruiken:

ls | perl -nle 'print if -d;'

Antwoord 22

Ik heb het gedeeltelijk opgelost met:

cd "/path/to/pricipal/folder"
for i in $(ls -d .*/); do sudo ln -s "$PWD"/${i%%/} /home/inukaze/${i%%/}; done

 

    ln: «/home/inukaze/./.»: can't overwrite a directory
    ln: «/home/inukaze/../..»: can't overwrite a directory
    ln: accesing to «/home/inukaze/.config»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.disruptive»: too much symbolics links levels
    ln: accesing to «/home/inukaze/innovations»: too much symbolics links levels
    ln: accesing to «/home/inukaze/sarl»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.e_old»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.gnome2_private»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.gvfs»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.kde»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.local»: too much symbolics links levels
    ln: accesing to «/home/inukaze/.xVideoServiceThief»: too much symbolics links levels

Nou, dit is voor mij het grootste deel 🙂


Antwoord 23

Toevoegen om het een volledige cirkel te maken, om het pad van elke map op te halen, gebruik een combinatie van het antwoord van Albert en Gordans. Dat zou best handig moeten zijn.

for i in $(ls -d /pathto/parent/folder/*/); do echo ${i%%/}; done

Uitvoer:

/pathto/parent/folder/childfolder1/
/pathto/parent/folder/childfolder2/
/pathto/parent/folder/childfolder3/
/pathto/parent/folder/childfolder4/
/pathto/parent/folder/childfolder5/
/pathto/parent/folder/childfolder6/
/pathto/parent/folder/childfolder7/
/pathto/parent/folder/childfolder8/

Antwoord 24

Hier is een variatie die gebruikmaakt van tree die directorynamen alleen op afzonderlijke regels uitvoert, ja het is lelijk, maar hey, het werkt.

tree -d | grep -E '^[+|L]' | cut -d ' ' -f2

of met awk

tree -d | grep -E '^[+|L]' | awk '{print $2}'

Dit is echter waarschijnlijk beter en behoudt de / achter de directorynaam.

ls -l | awk '/^d/{print $9}'

Antwoord 25

Om de oorspronkelijke vraag te beantwoorden, */ heeft op zich niets te maken met ls; het wordt gedaan door de shell/Bash, in een proces dat bekend staat als globbing.

Dit is de reden waarom echo */ en ls -d */ dezelfde elementen uitvoeren. (De vlag -d zorgt ervoor dat ls de directorynamen uitvoert en niet de inhoud van de directory’s.)


Antwoord 26

Dit is wat ik gebruik om alleen directorynamen weer te geven:

ls -1d /some/folder/*/ | awk -F "/" "{print \$(NF-1)}"

Antwoord 27

als je ruimte hebt in je mapnaam $9, zal print niet werken, probeer dan onderstaande opdracht

ls -l yourfolder/alldata/ | grep '^d' | awk '{print $9" " $10}'

uitvoer

ls -l yourfolder/alldata/ | grep '^d' | awk '{print $9" " $10}'
testing_Data 
Folder 1

LEAVE A REPLY

Please enter your comment!
Please enter your name here

three × 1 =

Other episodes