using "touch" to create directories? [closed] - linux

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 12 years ago.
Improve this question
1) in the "A" directory:
find . -type f > a.txt
2) in the "B" directory:
cat a.txt | while read FILENAMES; do touch "$FILENAMES"; done
3) Result: the 2) "creates the files" [i mean only with the same filename, but with 0 Byte size] ok. But if there are subdirs in the "A" directory, then the 2) can't create the files in the subdir, because there are no directories in it.
Question: is there a way, that touch can create directories?

Since find outputs one file per line:
cat a.txt | while read file; do
if [[ "$file" = */* ]]; then
mkdir -p "${file%/*}";
fi;
touch "$file";
done
EDIT:
This would be slightly more efficient if the directories where created in a separate step:
cat a.txt | grep / | sed 's|/[^/]*$||' | sort -u | xargs -d $'\n' mkdir -p
cat a.txt | while read file; do
touch "$file";
done
And, no, touch cannot create directories on its own.

No. Why not just use mkdir instead of touch for directories?

Related

Empty a file in linux bash [duplicate]

This question already has answers here:
Unix shell script to truncate a large file
(4 answers)
Closed 3 years ago.
which one is the best way to clean or empty a file in Linux?
I have to zip ( tar ) a file to an archive and then clean/empty it; this is what I do and it works correctly:
tar -zcvf /mnt/file.tar.gz /mnt/file.txt > /dev/null 2>&1
echo "" > /mnt/file.txt
I'm doing it with echo, probably there is a better way ?
Thanks
There are multiple ways to do that:
We presume that our file is called access.log and it's in the current directory:
1.
: > access.log
2.
true > access.log
3.
cat /dev/null > access.log
4.
cp /dev/null access.log
5.
dd if=/dev/null of=access.log
6.
echo -n "" > access.log
7.
echo -n > access.log
Just truncate it:
truncate -s 0 file
one option is:
touch passbook.txt
Another option to make empty file in Linux is just type the following command:
> file-name-here
echo '' > filename
ls filename
file filename
EDIT(zipping file and nullifying actual file): Taking inspiration from #oguz ismail's fine answer, I am using truncate option with zip of the file too here.
tar -zcvf file.tar.gz file.txt && truncate -s 0 file.txt
I will go with > /mnt/file.txt a bit easier than echo.
tar czvf /tmp/empty.tar.gz --files-from=/dev/null --overwrite
I found a way here

How to write a "bash script.sh argument " [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
hi can someone help me with this.
How to Write a script that takes in as argument a filename and displays its modification date and time in this way exactly :
[user#localhost...]$ bash script.sh temp.txt
the file temp.txt was modified on May 1 20:20
And then modify that script in such a way that it lists the modification dates for directories whose names contain a given pattern in this way exactly :
[user#local....]$ bash script.sh testRegex Pub
the file testRegex was modified on May 1 20:22
the directory /home/user/Public was modified on Dec 26 08:00
the directory /home/user/Pubs. was modified on May 2 20:00
please help I need to answer this fast
Thanks
This is pretty simple to do actually. You should read up on the stat command as #John Bollinger said. I also used the date command to format the date. You can read up on taking arguments for a script here
Combining all of this would give -
#!/bin/bash
filename=$1;
dirname=$2;
file_mod_date=`date -d #$( stat -c %Y $1 ) +%m" "%B" "%H:%M`;
echo "The file ${filename} was modified on ${file_mod_date}";
if [ "$2" == "" ]; then
exit 1;
else
for i in /home/user/*${dirname}*/; do
dir_mod_date=`date -d #$( stat -c %Y $i ) +%m" "%B" "%H:%M`;
echo "The directory ${i} was modified on ${dir_mod_date}";
done
fi
A good way to do this is with passing options and values:
For example:
file_name=""
help_message="To use this script type script.sh --file /path/to/file.txt"
# -- Get input options (if any)
while [[ $# > 0 ]] ;do
key="$1"
case ${key,,} in
-f|--file)
file_name="${2,,}"
shift
;;
-h|--help)
echo -e "$help_message"
exit;
shift
;;
esac
shift
done
Call the script like this:
bash script.sh -f "temp.txt"
With regard to the "logic" of the script, you will have to figure that out ;-)

Creating a Script that will create user accounts (using useradd) from a .txt file of usernames [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I need to create a script that will create user accounts (using useradd) from a .txt file of usernames. Please help me because my professor has not been the best of help.
The text file's name is users.txt
The only in the file is usernames, we are suppose to set up a default password and have it where they must change it on the next logon. We are also supposed to add them into a group called interns.
Here is what I have so far:
#!/bin/bash
for i in users.txt
do
sudo echo $i
sudo useradd $i -m -d /home/$i -s /bin/bash $i -G sudo interns $i
passwd = echo "AIST2330password" | passwd -stdin $i
sudo passwd -e $i
echo "User must change password when they come back"
done
This line:
for i in users.txt
should be:
for i in $(cat users.txt)
Your code is iterating over the literal string users.txt, not the contents of the file.
And this line:
passwd = echo "AIST2330password" | passwd -stdin $i
should be:
echo "$i:AIST2330password" | chpasswd
because the --stdin option to passwd has been deprecated.

Show file contents after searching word Done [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I need to display the file contents after searching for a word. If the word is found, display the file.
My code is below:
GNU nano 2.2.6 File: work
#!/bin/bash
while read -p "Welcome what would you like to do (S) to search or (Q) to quit " option
do
case $option in
"S") echo "What is the name of the file you would like to search for?"
read file
echo "What word would you like to find in the file?"
read word
grep -q $word $file
if [ $? -eq 0 ]; then
echo "$word found in $file"
cat $file
else
echo "$word NOT found in $file"
fi
;;
"Q") echo "Goodbye!"
exit ;;
*) echo "invalid option" ;;
esac
done
Replace
echo $file
with
cat $file
I believe you are looking for command cat $file. Stick it inside of your if block.
I need to load up what a file says with out loading up the file.
There is no way to access the contents of the file without accessing the file.
grep -l word file | xargs -r cat
shows file content if word is found. This also shows name of file
grep -l word file | xargs -r -i bash -c "echo {}:; cat {}"

How can I show the wget progress bar only? [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
For example:
wget http://somesite.com/TheFile.jpeg
downloading: TheFile.tar.gz ...
--09:30:42-- http://somesite.com/TheFile.jpeg
=> `/home/me/Downloads/TheFile.jpeg'
Resolving somesite.co... xxx.xxx.xxx.xxx.
Connecting to somesite.co|xxx.xxx.xxx.xxx|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1,614,820 (1.5M) [image/jpeg]
25% [======> ] 614,424 173.62K/s ETA 00:14
How can I get it to look like the following?
downloading: TheFile.jpeg ...
25% [======> ] 614,424 173.62K/s ETA 00:14
I know curl can do that. However, I need to get wget to do that job.
Use:
wget http://somesite.com/TheFile.jpeg -q --show-progress
-q: Turn off wget's output
--show-progress: Force wget to display the progress bar no matter what its verbosity level is set to
You can use the following filter:
progressfilt ()
{
local flag=false c count cr=$'\r' nl=$'\n'
while IFS='' read -d '' -rn 1 c
do
if $flag
then
printf '%s' "$c"
else
if [[ $c != $cr && $c != $nl ]]
then
count=0
else
((count++))
if ((count > 1))
then
flag=true
fi
fi
fi
done
}
Usage:
$ wget --progress=bar:force http://somesite.com/TheFile.jpeg 2>&1 | progressfilt
100%[======================================>] 15,790 48.8K/s in 0.3s
2011-01-13 22:09:59 (48.8 KB/s) - 'TheFile.jpeg' saved [15790/15790]
This function depends on a sequence of 0x0d0x0a0x0d0x0a0x0d being sent right before the progress bar is started. This behavior may be implementation dependent.
Run using these flags:
wget -q --show-progress --progress=bar:force 2>&1
You can use the follow option of tail:
wget somesite.com/TheFile.jpeg --progress=bar:force 2>&1 | tail -f -n +6
The +6 is to delete the first 6 lines. It may be different on your version of wget or your language.
You need to use --progress=bar:force otherwise wget switches to the dot type.
The downside is that the refreshing is less frequent than with wget (looks like every 2 seconds). The --sleep-interval option of tail seems to be meant just for that, but it didn't change anything for me.
The option --show-progress, as pointed out by others, is the best option, but it is available only since GNU wget 1.16, see Noteworthy changes in wget 1.16.
To be safe, we can first check if --show-progress is supported:
# set progress option accordingly
wget --help | grep -q '\--show-progress' && \
_PROGRESS_OPT="-q --show-progress" || _PROGRESS_OPT=""
wget $_PROGRESS_OPT ...
Maybe it's time to consider just using curl.
You can use standard options:
wget --progress=bar http://somesite.com/TheFile.jpeg
This is another example:
download() {
local url=$1
echo -n " "
wget --progress=dot $url 2>&1 | grep --line-buffered "%" | sed -u -e "s,\.,,g" | awk '{printf("\b\b\b\b%4s", $2)}'
echo -ne "\b\b\b\b"
echo " DONE"
}
Here is a solution that will show you a dot for each file (or line, for that matter). It is particularly useful if you are downloading with --recursive. This won't catch errors and may be slightly off if there are extra lines, but for general progress on a lot of files it is helpful:
wget -r -nv https://example.com/files/ | \
awk -v "ORS=" '{ print "."; fflush(); } END { print "\n" }'
This is not literally an answer but this snippet might also be helpful to some coming here for e.g. "zenity wget GUI":
LANG=C wget -O /dev/null --progress=bar:force:noscroll --limit-rate 5k http://nightly.altlinux.org/sisyphus/ChangeLog 2>&1 | stdbuf -i0 -o0 -e0 tr '>' '\n' | stdbuf -i0 -o0 -e0 sed -rn 's/^.*\<([0-9]+)%\[.*$/\1/p' | zenity --progress --auto-close
What was crucial for me is stdbuf(1).

Resources